搜 索

vLLM:大模型推理的速度与激情

  • 2阅读
  • 2025年05月03日
  • 0评论
首页 / AI/大数据 / 正文

前言:推理的瓶颈在哪里?

你训练好了一个大模型,部署上线,结果发现:

  • 单次请求延迟 5 秒
  • 并发 10 个用户就卡死
  • GPU 利用率只有 30%
  • 每天的 GPU 费用让你肉疼

问题出在哪?

大模型推理有两个阶段:

  1. Prefill(预填充):处理用户输入,计算密集型
  2. Decode(解码):逐个生成 token,内存密集型
graph LR subgraph 推理过程 A[用户输入
100 tokens] --> B[Prefill
并行处理] B --> C[生成 token 1] C --> D[生成 token 2] D --> E[...] E --> F[生成 token N] end subgraph 时间占比 B2[Prefill: 10%] C2[Decode: 90%] end style C2 fill:#ff6b6b

Decode 阶段是瓶颈! 每生成一个 token 都要:

  1. 读取整个 KV Cache
  2. 做一次完整的前向传播
  3. 只产出一个 token

GPU 的计算能力被浪费了,大部分时间在等待内存读写。

vLLM 的使命:让 GPU 不再"摸鱼"。


一、LLM 推理为什么慢?

1.1 自回归生成的本质

LLM 生成文本是自回归的——每次只能生成一个 token:

def naive_generate(model, prompt, max_tokens):
    """朴素的生成方式"""
    tokens = tokenize(prompt)
    
    for _ in range(max_tokens):
        # 每次都要处理所有已有的 tokens
        logits = model.forward(tokens)  # O(n) 复杂度
        next_token = sample(logits[-1])
        tokens.append(next_token)
        
        if next_token == EOS:
            break
    
    return tokens

生成 100 个 token 需要 100 次前向传播!

1.2 KV Cache:用空间换时间

为了避免重复计算,使用 KV Cache 缓存历史的 Key 和 Value:

graph TB subgraph 没有KVCache A1[Token 1] --> C1[计算 K1, V1] A2[Token 1,2] --> C2[计算 K1,K2, V1,V2] A3[Token 1,2,3] --> C3[计算 K1,K2,K3, V1,V2,V3] end subgraph 有KVCache B1[Token 1] --> D1[计算 K1,V1 → 缓存] B2[Token 2] --> D2[计算 K2,V2 → 缓存
复用 K1,V1] B3[Token 3] --> D3[计算 K3,V3 → 缓存
复用 K1,K2,V1,V2] end style D1 fill:#4ecdc4 style D2 fill:#4ecdc4 style D3 fill:#4ecdc4

KV Cache 大小计算

def calculate_kv_cache_size(
    batch_size: int,
    seq_len: int,
    num_layers: int,
    num_heads: int,
    head_dim: int,
    dtype_bytes: int = 2,  # FP16
):
    """计算 KV Cache 大小"""
    
    # 每层需要存储 K 和 V
    # 形状: [batch, num_heads, seq_len, head_dim]
    per_layer = 2 * batch_size * num_heads * seq_len * head_dim * dtype_bytes
    
    total = per_layer * num_layers
    
    return total / (1024 ** 3)  # GB


# LLaMA-7B 的 KV Cache
kv_cache_gb = calculate_kv_cache_size(
    batch_size=1,
    seq_len=4096,
    num_layers=32,
    num_heads=32,
    head_dim=128,
)
print(f"KV Cache 大小: {kv_cache_gb:.2f} GB")
# 输出: KV Cache 大小: 2.00 GB

问题:KV Cache 随序列长度线性增长,显存很快就不够了!

1.3 内存碎片问题

传统的 KV Cache 管理方式会产生大量内存碎片

graph TB subgraph 显存布局问题 M1["请求1 KV Cache
[已用 1000] [预留 3096]"] M2["请求2 KV Cache
[已用 500] [预留 3596]"] M3["请求3 KV Cache
[已用 2000] [预留 2096]"] M4["碎片
[浪费的空间]"] end style M4 fill:#ff6b6b

问题

  • 必须预先分配最大长度的空间
  • 短请求浪费大量显存
  • 无法高效批处理

二、vLLM 的核心创新:PagedAttention

2.1 灵感来源:操作系统的虚拟内存

操作系统如何管理内存?分页(Paging)

  • 内存被划分为固定大小的"页"
  • 不需要连续分配
  • 按需分配,用完释放

vLLM 把这个思想用到了 KV Cache 管理上。

2.2 PagedAttention 原理

graph TB subgraph 传统方式 T1[请求1] --> TC1["连续内存块
[K1,K2,K3,...,K4096]"] T2[请求2] --> TC2["连续内存块
[K1,K2,K3,...,K4096]"] end subgraph PagedAttention P1[请求1] --> PT1["逻辑块表"] P2[请求2] --> PT2["逻辑块表"] PT1 --> PH1["物理块 0"] PT1 --> PH2["物理块 3"] PT1 --> PH3["物理块 7"] PT2 --> PH4["物理块 1"] PT2 --> PH2 PT2 --> PH5["物理块 5"] end style PH2 fill:#4ecdc4

关键创新

  1. 分块存储:KV Cache 被分成固定大小的块(如 16 tokens)
  2. 非连续分配:块可以在显存中任意位置
  3. 动态分配:用多少分配多少,用完释放
  4. 共享机制:相同的前缀可以共享 KV Cache(如 PH2)

2.3 内存利用率对比

pie showData title 传统方式显存利用 "实际使用" : 30 "预留浪费" : 50 "碎片" : 20
pie showData title PagedAttention显存利用 "实际使用" : 90 "管理开销" : 5 "碎片" : 5

效果:显存利用率从 30% 提升到 90%+!

2.4 PagedAttention 代码示意

class PagedAttention:
    """PagedAttention 简化示意"""
    
    def __init__(self, block_size=16, num_blocks=1000):
        self.block_size = block_size
        self.num_blocks = num_blocks
        
        # 物理块池
        self.physical_blocks = torch.zeros(
            num_blocks, block_size, hidden_size
        )
        
        # 空闲块列表
        self.free_blocks = list(range(num_blocks))
        
        # 每个请求的块表
        self.block_tables = {}  # request_id -> [block_ids]
    
    def allocate_block(self, request_id):
        """为请求分配一个新块"""
        if not self.free_blocks:
            raise MemoryError("显存不足")
        
        block_id = self.free_blocks.pop()
        
        if request_id not in self.block_tables:
            self.block_tables[request_id] = []
        
        self.block_tables[request_id].append(block_id)
        return block_id
    
    def free_request(self, request_id):
        """释放请求的所有块"""
        if request_id in self.block_tables:
            self.free_blocks.extend(self.block_tables[request_id])
            del self.block_tables[request_id]
    
    def get_kv_cache(self, request_id, position):
        """获取指定位置的 KV Cache"""
        block_idx = position // self.block_size
        offset = position % self.block_size
        
        block_id = self.block_tables[request_id][block_idx]
        return self.physical_blocks[block_id, offset]
    
    def attention(self, query, request_id, seq_len):
        """执行分页注意力"""
        # 收集所有相关的 KV Cache 块
        block_ids = self.block_tables[request_id]
        
        # 重组为连续张量(或使用 CUDA kernel 直接处理)
        keys = []
        values = []
        for i, block_id in enumerate(block_ids):
            start = i * self.block_size
            end = min(start + self.block_size, seq_len)
            actual_len = end - start
            
            keys.append(self.physical_blocks[block_id, :actual_len, :hidden//2])
            values.append(self.physical_blocks[block_id, :actual_len, hidden//2:])
        
        k = torch.cat(keys, dim=0)
        v = torch.cat(values, dim=0)
        
        # 标准注意力计算
        attn = torch.softmax(query @ k.T / sqrt(d), dim=-1)
        output = attn @ v
        
        return output

三、vLLM 的其他优化

3.1 Continuous Batching(连续批处理)

传统批处理的问题:

sequenceDiagram participant R1 as 请求1 (生成100个token) participant R2 as 请求2 (生成10个token) participant R3 as 请求3 (生成50个token) Note over R1,R3: 传统批处理:等最长的完成 R1->>R1: 生成中... R2->>R2: 生成完成,等待中... R3->>R3: 生成完成,等待中... R1->>R1: 还在生成... Note over R1,R3: R2, R3 白白等待!

Continuous Batching

sequenceDiagram participant R1 as 请求1 participant R2 as 请求2 participant R3 as 请求3 participant R4 as 请求4 Note over R1,R4: 连续批处理:动态调度 R1->>R1: 生成中... R2->>R2: 完成! Note over R2: 立即返回 R4->>R4: 新请求加入 R3->>R3: 完成! Note over R3: 立即返回 R1->>R1: 完成!

效果

  • 短请求不用等长请求
  • GPU 始终满载
  • 吞吐量大幅提升

3.2 Prefix Caching(前缀缓存)

很多请求有相同的前缀(如 system prompt):

# 请求 1
messages = [
    {"role": "system", "content": "You are a helpful assistant."},  # 相同
    {"role": "user", "content": "What is AI?"}
]

# 请求 2
messages = [
    {"role": "system", "content": "You are a helpful assistant."},  # 相同
    {"role": "user", "content": "Tell me a joke."}
]

Prefix Caching:共享相同前缀的 KV Cache!

graph TB subgraph 无前缀缓存 R1[请求1] --> K1[计算 system prompt KV] R2[请求2] --> K2[计算 system prompt KV] R3[请求3] --> K3[计算 system prompt KV] end subgraph 有前缀缓存 P[System Prompt] --> PK[共享 KV Cache] R4[请求1] --> PK R5[请求2] --> PK R6[请求3] --> PK end style PK fill:#4ecdc4

3.3 Speculative Decoding(投机解码)

用小模型"猜测"多个 token,大模型验证:

sequenceDiagram participant Small as 小模型 (Draft) participant Large as 大模型 (Target) Small->>Small: 快速生成 5 个候选 token Small->>Large: 发送候选 tokens Large->>Large: 并行验证 5 个 token Large->>Large: 接受前 3 个,拒绝后 2 个 Note over Small,Large: 一次验证 = 生成 3 个 token!

加速原理

  • 小模型快,多生成几个猜测
  • 大模型并行验证(比逐个生成快)
  • 猜对的直接用,猜错的重新生成

3.4 Tensor Parallelism(张量并行)

单卡装不下?多卡并行!

graph LR subgraph 张量并行 Input[输入] --> GPU0[GPU 0: 前半部分] Input --> GPU1[GPU 1: 后半部分] GPU0 --> Sync[AllReduce 同步] GPU1 --> Sync Sync --> Output[输出] end

vLLM 支持多种并行策略:

  • Tensor Parallel:切分矩阵
  • Pipeline Parallel:切分层

四、vLLM 实战

4.1 安装

# 安装 vLLM
pip install vllm

# 或者从源码安装(最新特性)
pip install git+https://github.com/vllm-project/vllm.git

4.2 离线推理

from vllm import LLM, SamplingParams


def offline_inference():
    """离线批量推理"""
    
    # 加载模型
    llm = LLM(
        model="meta-llama/Llama-2-7b-chat-hf",
        tensor_parallel_size=1,  # GPU 数量
        dtype="half",            # FP16
        max_model_len=4096,      # 最大序列长度
    )
    
    # 采样参数
    sampling_params = SamplingParams(
        temperature=0.7,
        top_p=0.9,
        max_tokens=256,
        stop=["</s>", "[INST]"],
    )
    
    # 批量请求
    prompts = [
        "[INST] What is machine learning? [/INST]",
        "[INST] Write a Python function to sort a list. [/INST]",
        "[INST] Explain quantum computing in simple terms. [/INST]",
    ]
    
    # 生成
    outputs = llm.generate(prompts, sampling_params)
    
    # 处理结果
    for output in outputs:
        prompt = output.prompt
        generated = output.outputs[0].text
        print(f"Prompt: {prompt[:50]}...")
        print(f"Generated: {generated[:100]}...")
        print("-" * 50)


if __name__ == "__main__":
    offline_inference()

4.3 在线服务(OpenAI 兼容 API)

# 启动服务
python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Llama-2-7b-chat-hf \
    --host 0.0.0.0 \
    --port 8000 \
    --tensor-parallel-size 1
# 客户端调用
import openai

client = openai.OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="not-needed",  # vLLM 不需要 API key
)

# Chat Completion
response = client.chat.completions.create(
    model="meta-llama/Llama-2-7b-chat-hf",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "What is deep learning?"},
    ],
    temperature=0.7,
    max_tokens=256,
)

print(response.choices[0].message.content)


# 流式输出
stream = client.chat.completions.create(
    model="meta-llama/Llama-2-7b-chat-hf",
    messages=[{"role": "user", "content": "Tell me a story."}],
    stream=True,
)

for chunk in stream:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

4.4 使用量化模型

from vllm import LLM, SamplingParams


def use_quantized_model():
    """使用量化模型"""
    
    # AWQ 量化模型
    llm_awq = LLM(
        model="TheBloke/Llama-2-7B-AWQ",
        quantization="awq",
        dtype="half",
    )
    
    # GPTQ 量化模型
    llm_gptq = LLM(
        model="TheBloke/Llama-2-7B-GPTQ",
        quantization="gptq",
        dtype="half",
    )
    
    # 使用
    sampling_params = SamplingParams(temperature=0.7, max_tokens=100)
    outputs = llm_awq.generate(["Hello, how are you?"], sampling_params)
    
    return outputs

4.5 多 GPU 部署

from vllm import LLM, SamplingParams


def multi_gpu_inference():
    """多 GPU 推理"""
    
    # 自动使用多张 GPU
    llm = LLM(
        model="meta-llama/Llama-2-70b-chat-hf",
        tensor_parallel_size=4,  # 使用 4 张 GPU
        dtype="half",
    )
    
    # 70B 模型需要 ~140GB 显存 (FP16)
    # 4 张 A100 40GB 刚好够用
    
    sampling_params = SamplingParams(temperature=0.7, max_tokens=256)
    outputs = llm.generate(["What is the meaning of life?"], sampling_params)
    
    return outputs


# 或者使用命令行
# python -m vllm.entrypoints.openai.api_server \
#     --model meta-llama/Llama-2-70b-chat-hf \
#     --tensor-parallel-size 4 \
#     --port 8000

4.6 高级配置

from vllm import LLM, SamplingParams
from vllm.engine.arg_utils import EngineArgs


def advanced_config():
    """高级配置示例"""
    
    llm = LLM(
        model="meta-llama/Llama-2-7b-chat-hf",
        
        # 显存管理
        gpu_memory_utilization=0.9,    # GPU 显存利用率
        max_model_len=8192,            # 最大序列长度
        
        # 批处理
        max_num_batched_tokens=8192,   # 批处理最大 token 数
        max_num_seqs=256,              # 最大并发序列数
        
        # 量化
        quantization=None,             # "awq", "gptq", "squeezellm"
        
        # 并行
        tensor_parallel_size=1,
        pipeline_parallel_size=1,
        
        # 精度
        dtype="auto",                  # "half", "float16", "bfloat16", "float"
        
        # 优化
        enforce_eager=False,           # 禁用 CUDA Graph(调试用)
        enable_prefix_caching=True,    # 启用前缀缓存
        
        # 投机解码
        speculative_model=None,        # 小模型路径
        num_speculative_tokens=5,      # 投机生成的 token 数
    )
    
    return llm


# 采样参数详解
sampling_params = SamplingParams(
    # 基础参数
    temperature=0.7,           # 温度,越高越随机
    top_p=0.9,                 # nucleus sampling
    top_k=50,                  # top-k sampling
    max_tokens=256,            # 最大生成长度
    
    # 停止条件
    stop=["</s>", "\n\n"],     # 停止词
    stop_token_ids=[2],        # 停止 token ID
    
    # 高级参数
    presence_penalty=0.0,      # 存在惩罚
    frequency_penalty=0.0,     # 频率惩罚
    repetition_penalty=1.0,    # 重复惩罚
    
    # 输出控制
    n=1,                       # 生成几个候选
    best_of=1,                 # 从几个中选最好的
    use_beam_search=False,     # 是否使用 beam search
    
    # Logprobs
    logprobs=None,             # 返回 top-k logprobs
    prompt_logprobs=None,      # 返回 prompt 的 logprobs
)

五、性能调优

5.1 关键性能指标

def benchmark_vllm(llm, prompts, sampling_params):
    """性能基准测试"""
    import time
    
    start = time.time()
    outputs = llm.generate(prompts, sampling_params)
    end = time.time()
    
    # 统计
    total_time = end - start
    num_prompts = len(prompts)
    total_tokens = sum(len(o.outputs[0].token_ids) for o in outputs)
    
    # 指标
    throughput = total_tokens / total_time  # tokens/秒
    latency = total_time / num_prompts      # 秒/请求
    
    print(f"总时间: {total_time:.2f}s")
    print(f"吞吐量: {throughput:.1f} tokens/s")
    print(f"平均延迟: {latency:.3f}s/request")
    print(f"总生成 tokens: {total_tokens}")
    
    return throughput, latency

5.2 性能优化清单

mindmap root((vLLM 性能优化)) 显存优化 gpu_memory_utilization 调高 使用量化模型 减少 max_model_len 吞吐优化 增加 max_num_seqs 增加 batch size 启用 prefix caching 延迟优化 使用 speculative decoding 减少 max_tokens 使用更快的模型 多卡优化 Tensor Parallel Pipeline Parallel

5.3 常见问题排查

def troubleshoot_vllm():
    """常见问题排查"""
    
    # 问题 1: CUDA OOM
    # 解决: 减少显存使用
    llm = LLM(
        model="...",
        gpu_memory_utilization=0.8,  # 降低利用率
        max_model_len=2048,          # 减少最大长度
    )
    
    # 问题 2: 吞吐量低
    # 解决: 增加并发
    llm = LLM(
        model="...",
        max_num_seqs=512,            # 增加并发数
        max_num_batched_tokens=16384,  # 增加批处理大小
    )
    
    # 问题 3: 首次推理慢
    # 原因: CUDA Graph 编译
    # 解决: 预热或禁用
    llm = LLM(
        model="...",
        enforce_eager=True,  # 禁用 CUDA Graph(会降低性能)
    )
    
    # 问题 4: 内存泄漏
    # 解决: 显式清理
    import gc
    import torch
    
    del llm
    gc.collect()
    torch.cuda.empty_cache()

5.4 性能对比

以 LLaMA-2-7B 为例,单张 A100 40GB:

框架吞吐量 (tokens/s)延迟 (ms/token)
HuggingFace30-5020-30
vLLM500-10001-2
TGI300-6002-5
TensorRT-LLM800-12000.8-1.5

vLLM 比原生 HuggingFace 快 10-20 倍!


六、生产部署最佳实践

6.1 Docker 部署

# Dockerfile
FROM vllm/vllm-openai:latest

# 复制模型(可选,也可以运行时下载)
# COPY ./model /model

# 启动服务
CMD ["--model", "meta-llama/Llama-2-7b-chat-hf", \
     "--port", "8000", \
     "--host", "0.0.0.0"]
# 构建和运行
docker build -t my-vllm .
docker run --gpus all -p 8000:8000 my-vllm

# 或者直接使用官方镜像
docker run --gpus all \
    -v ~/.cache/huggingface:/root/.cache/huggingface \
    -p 8000:8000 \
    vllm/vllm-openai:latest \
    --model meta-llama/Llama-2-7b-chat-hf

6.2 Kubernetes 部署

# vllm-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vllm-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: vllm
  template:
    metadata:
      labels:
        app: vllm
    spec:
      containers:
      - name: vllm
        image: vllm/vllm-openai:latest
        args:
        - "--model"
        - "meta-llama/Llama-2-7b-chat-hf"
        - "--port"
        - "8000"
        resources:
          limits:
            nvidia.com/gpu: 1
        ports:
        - containerPort: 8000
        volumeMounts:
        - name: model-cache
          mountPath: /root/.cache/huggingface
      volumes:
      - name: model-cache
        persistentVolumeClaim:
          claimName: model-cache-pvc

---
apiVersion: v1
kind: Service
metadata:
  name: vllm-service
spec:
  selector:
    app: vllm
  ports:
  - port: 80
    targetPort: 8000
  type: LoadBalancer

6.3 负载均衡

# 使用 FastAPI 做负载均衡
from fastapi import FastAPI
import httpx
import random

app = FastAPI()

# vLLM 实例列表
VLLM_SERVERS = [
    "http://vllm-1:8000",
    "http://vllm-2:8000",
    "http://vllm-3:8000",
]


@app.post("/v1/chat/completions")
async def chat_completions(request: dict):
    """负载均衡转发"""
    
    # 简单的随机负载均衡
    server = random.choice(VLLM_SERVERS)
    
    async with httpx.AsyncClient() as client:
        response = await client.post(
            f"{server}/v1/chat/completions",
            json=request,
            timeout=60.0,
        )
        return response.json()


@app.get("/health")
async def health_check():
    """健康检查"""
    healthy_servers = []
    
    async with httpx.AsyncClient() as client:
        for server in VLLM_SERVERS:
            try:
                resp = await client.get(f"{server}/health", timeout=5.0)
                if resp.status_code == 200:
                    healthy_servers.append(server)
            except:
                pass
    
    return {
        "healthy": len(healthy_servers),
        "total": len(VLLM_SERVERS),
        "servers": healthy_servers,
    }

6.4 监控和告警

# 使用 Prometheus 监控
from prometheus_client import Counter, Histogram, start_http_server
import time

# 定义指标
REQUEST_COUNT = Counter('vllm_requests_total', 'Total requests')
REQUEST_LATENCY = Histogram('vllm_request_latency_seconds', 'Request latency')
TOKENS_GENERATED = Counter('vllm_tokens_generated_total', 'Total tokens generated')


def monitored_generate(llm, prompts, sampling_params):
    """带监控的生成"""
    
    REQUEST_COUNT.inc(len(prompts))
    
    start = time.time()
    outputs = llm.generate(prompts, sampling_params)
    latency = time.time() - start
    
    REQUEST_LATENCY.observe(latency)
    
    total_tokens = sum(len(o.outputs[0].token_ids) for o in outputs)
    TOKENS_GENERATED.inc(total_tokens)
    
    return outputs


# 启动 Prometheus 指标服务
start_http_server(9090)

七、vLLM vs 其他框架

7.1 主流推理框架对比

graph TB subgraph 推理框架 vLLM["vLLM
PagedAttention
高吞吐"] TGI["TGI
HuggingFace 出品
易用"] TRT["TensorRT-LLM
NVIDIA 出品
极致性能"] Ollama["Ollama
本地部署
最简单"] end
框架优势劣势适用场景
vLLM高吞吐、易用功能较少通用服务部署
TGIHF 生态、功能全性能略低HF 模型部署
TensorRT-LLM极致性能配置复杂超大规模
Ollama最简单性能一般本地/开发

7.2 何时选择 vLLM?

flowchart TB A[选择推理框架] --> B{需求是什么?} B -->|高吞吐服务| C[vLLM ✓] B -->|本地快速体验| D[Ollama ✓] B -->|极致性能| E[TensorRT-LLM] B -->|HF 生态集成| F[TGI] C --> G[适合大多数场景] style C fill:#4ecdc4 style G fill:#4ecdc4

选择 vLLM 的理由

  • 开箱即用,配置简单
  • 性能足够好(90% 场景够用)
  • 社区活跃,更新快
  • OpenAI 兼容 API

八、总结

vLLM 核心要点

mindmap root((vLLM)) 核心创新 PagedAttention Continuous Batching Prefix Caching 性能优势 10-20倍吞吐提升 90%+显存利用率 低延迟 使用方式 离线推理 在线服务 OpenAI兼容API 部署 单机 多GPU Kubernetes

关键 Takeaway

  1. PagedAttention 是核心:借鉴操作系统分页,解决 KV Cache 内存管理问题
  2. 性能提升显著:比原生 HuggingFace 快 10-20 倍
  3. 使用简单:几行代码就能用,API 兼容 OpenAI
  4. 生产就绪:支持量化、多 GPU、Docker/K8s 部署
  5. 持续进化:社区活跃,新功能不断加入

快速开始模板

# 最简单的 vLLM 使用
from vllm import LLM, SamplingParams

llm = LLM(model="meta-llama/Llama-2-7b-chat-hf")
outputs = llm.generate(
    ["Hello, how are you?"],
    SamplingParams(temperature=0.7, max_tokens=100)
)
print(outputs[0].outputs[0].text)
# 最简单的 API 服务
python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Llama-2-7b-chat-hf \
    --port 8000

下一步学习

  • [ ] RAG:检索增强生成
  • [ ] Agent:让大模型自己干活
  • [ ] 多模态:不只是文本

参考资料

  1. vLLM Paper - Efficient Memory Management for LLM Serving with PagedAttention
  2. vLLM GitHub - 官方仓库
  3. vLLM Documentation - 官方文档
  4. Continuous Batching - Anyscale 博客
  5. Speculative Decoding - 投机解码论文

评论区
暂无评论
avatar