Skip to content
Self-Knowing

Config

约 444 个字 29 行代码 预计阅读时间 2 分钟

config.py 是 nano-vllm 的全局配置入口。它以 dataclass 的形式集中管理模型路径、显存策略、并行度和 KV cache 参数,初始化时自动校验并加载 HuggingFace 模型配置。

Sequence 和 Request 的区别

request 是外部用户提交的一次任务。

sequence 是调度器内部实际跑的一条生成路径。

vLLM 中可以配置 \(n > 1\):同一个 prompt,模型并行生成 5 个不同的候选回复,用户从中挑最好的。

sampling_params = SamplingParams(n=5, temperature=0.8, max_tokens=100)

在 nano-vllm 中,基本是一个 request 对应一个 sequence。

max_num 三个参数

max_model_len:单个序列的长度上限。一条序列 token 总数不得超过这个值。

max_num_seqs:一次前向最多并行多少个序列。限制的是数量。

max_num_batched_tokens:一次前向中,所有序列的 token 总和上限:∑(每个序列本次要处理的 token 数)。

用公式表达就是一次调度里头:

sum(seq.num_scheduled_tokens for seq in scheduled_seqs)  max_num_batched_tokens
len(scheduled_seqs)  max_num_seqs
每个 seq  len(seq)  max_model_len

三个条件同时满足,缺一不可。

eager mode

eager mode 下,每个 CUDA 算子都是一次独立的「CPU 发指令 → GPU 执行 → CPU 等结果」的循环。decode 阶段 batch 很小(可能只有几个序列),每个矩阵乘法、每个 RoPE、每个 RMSNorm 都没什么数据要算,但 CPU 给 GPU 发指令的延迟本身是固定的。结果是 100 个很小的 kernel 各跑 5 微秒,但 CPU 发起它们花了 500 微秒,大半时间浪费在通信上。

CUDA Graph 的做法是:把这些 kernel 调用的全部序列录成一盘磁带,录制完之后 replay 只要一个指令——你说「放」,GPU 把整盘磁带从头到尾跑完。100 次 CPU→GPU 通信变成 1 次。

enforce_eager = True,每一步都老老实实走 eager,方便调试。

Source Code

import os
from dataclasses import dataclass
from transformers import AutoConfig


@dataclass(slots=True)
class Config:
    model: str                                  # 模型本地路径,必须是目录
    max_num_batched_tokens: int = 16384         # 单次前向最大 token 数,超了就分 chunk
    max_num_seqs: int = 512                     # 单次前向最多并行多少个序列
    max_model_len: int = 4096                   # 最大上下文长度,最终会跟 hf_config 取较小值
    gpu_memory_utilization: float = 0.9         # 显存分配给 KV cache 的上限比例,留 10% 给中间激活
    tensor_parallel_size: int = 1               # 张量并行 GPU 数,1~8,>1 时 QKV/MLP 权重切片分卡
    enforce_eager: bool = False                 # 禁用 CUDA Graph,默认关闭以允许 decode 阶段走录制图加速
    hf_config: AutoConfig | None = None         # 从 model/ 自动加载的 HF 模型配置,无需手动传
    eos: int = -1                               # EOS token id,仅占位,真实值在 LLMEngine 里从 tokenizer 取
    kvcache_block_size: int = 256               # 每个 KV cache block 装多少个 token,须为 256 的整数倍
    num_kvcache_blocks: int = -1                # KV cache 总 block 数,-1 表示由 allocate_kv_cache() 根据可用显存反算

    def __post_init__(self):
        assert os.path.isdir(self.model)
        assert self.kvcache_block_size % 256 == 0
        assert 1 <= self.tensor_parallel_size <= 8
        self.hf_config = AutoConfig.from_pretrained(self.model)
        self.max_model_len = min(self.max_model_len, self.hf_config.max_position_embeddings)

Created: May 4, 2026
Last update: May 5, 2026

Discussion