Config¶
约 444 个字 29 行代码 预计阅读时间 2 分钟
config.py 是 nano-vllm 的全局配置入口。它以 dataclass 的形式集中管理模型路径、显存策略、并行度和 KV cache 参数,初始化时自动校验并加载 HuggingFace 模型配置。
Sequence 和 Request 的区别¶
request 是外部用户提交的一次任务。
sequence 是调度器内部实际跑的一条生成路径。
vLLM 中可以配置 \(n > 1\):同一个 prompt,模型并行生成 5 个不同的候选回复,用户从中挑最好的。
在 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)
Last update: May 5, 2026
Discussion