跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

[AI][vLLM] max_num_seqs 参数详解

max_num_seqs 参数详解 一、参数定义

max_num_seqs

是 vLLM 和 vLLM-Ascend 中一个关键的调度配置参数,用于限制 单个调度步骤中同时处理的最大序列(请求)数量 。

默认值 默认值 : 128 位置 :

vllm/vllm/config/scheduler.py

中的

SchedulerConfig.DEFAULT_MAX_NUM_SEQS DEFAULT_MAX_NUM_SEQS: ClassVar[int] = 128

二、核心作用 1. 调度器层面的限制 在调度器(Scheduler)中,

max_num_seqs

被转换为

max_num_running_reqs

,用于限制 同时处于运行状态(RUNNING)的请求数量 。

代码位置 :

vllm/vllm/v1/core/sched/scheduler.py # 第97行

self.max_num_running_reqs = self.scheduler_config.max_num_seqs

调度逻辑 :

# 第428-429行:当运行中的请求数达到上限时,停止从等待队列中调度新请求

if len(self.running) == self.max_num_running_reqs: break

这意味着: 如果当前有 128 个请求正在运行(

max_num_seqs=128

),新的请求将停留在等待队列(WAITING)中 只有当某个运行中的请求完成或被抢占后,等待队列中的请求才能被调度 2. 内存分配和缓冲区大小

max_num_seqs

直接影响 Worker 中各种缓冲区的分配大小。

2.1 RequestState 缓冲区 代码位置 :

vllm/vllm/v1/worker/gpu/states.py RequestState

类使用

max_num_reqs

(即

max_num_seqs

)来分配所有请求相关的状态缓冲区:

class RequestState:

def __init__(self, max_num_reqs: int, ...): # 为每个请求分配固定大小的缓冲区 self.prompt_len = np.zeros(self.max_num_reqs, dtype=np.int32) self.prefill_token_ids = UvaBuffer( self.max_num_reqs, self.max_model_len, dtype=torch.int32 ) self.prefill_len = self._make_buffer(self.max_num_reqs, dtype=torch.int32) self.num_computed_tokens = torch.zeros( self.max_num_reqs, dtype=torch.int32, device=device ) # ... 更多缓冲区

内存影响 :

prefill_token_ids

: 大小为

max_num_reqs × max_model_len × 4字节

(int32) 例如:128 × 32768 × 4 = 16MB(仅这一个缓冲区) 所有请求状态缓冲区的总大小与

max_num_seqs

成正比 2.2 InputBuffers 缓冲区 代码位置 :

vllm/vllm/v1/worker/gpu/model_runner.py self.input_buffers = InputBuffers(

max_num_reqs=self.max_num_reqs, # 使用 max_num_seqs max_num_tokens=self.max_num_tokens, ... )

InputBuffers

用于存储每个推理步骤的输入数据,其大小也受

max_num_seqs

影响。

2.3 BlockTables 缓冲区 代码位置 :

vllm/vllm/v1/worker/gpu/model_runner.py self.block_tables = BlockTables(

block_sizes=block_sizes, max_num_reqs=self.max_num_reqs, # 使用 max_num_seqs max_num_batched_tokens=self.max_num_tokens, ... )

BlockTables 用于管理 KV Cache 的块表,其大小也与

max_num_seqs

相关。

3. 数据并行(DP)场景下的特殊含义 在 vLLM-Ascend 的文档中明确指出:

--max-num-seqs

表示 每个 DP group 允许处理的最大请求数 。

如果发送到服务的请求数超过此限制,多余的请求将保持在等待状态,不会被调度。

重要公式 :

总并发能力 = max_num_seqs × data_parallel_size

示例 : 如果

max_num_seqs=16

data_parallel_size=2

那么总共有 16 × 2 = 32 个请求可以同时运行 如果实际并发请求数为 40,那么有 8 个请求会处于等待状态 性能测试建议 : 在测试性能时,一般建议

max_num_seqs × data_parallel_size >= 实际总并发数

,否则等待时间也会被计入 TTFT(Time To First Token)和 TPOT(Time Per Output Token)等指标中。

4. 与 max_num_batched_tokens 的关系

max_num_seqs

max_num_batched_tokens

共同决定了批处理的能力: 验证逻辑 (

vllm/vllm/config/scheduler.py

):

# 第264-269行:max_num_batched_tokens 必须 >= max_num_seqs

if self.max_num_batched_tokens < self.max_num_seqs: raise ValueError( f"max_num_batched_tokens ({self.max_num_batched_tokens}) must " "be greater than or equal to max_num_seqs " f"({self.max_num_seqs})." )

关系说明 :

max_num_batched_tokens

: 限制单次推理步骤中处理的 总 token 数

max_num_seqs

: 限制单次推理步骤中处理的 总请求数 理论上,如果每个请求只有 1 个 token,最多可以处理

max_num_batched_tokens

个请求 但实际上,由于

max_num_seqs

的限制,最多只能处理

max_num_seqs

个请求 警告逻辑 (第271-277行):

if self.max_num_batched_tokens > self.max_num_seqs * max_model_len:

logger.warning( "max_num_batched_tokens (%d) exceeds max_num_seqs " "* max_model_len (%d). This may lead to unexpected behavior.", ... )

三、影响范围 1. 内存占用 直接影响 : 所有请求状态缓冲区的大小 InputBuffers 的大小 BlockTables 的大小 采样参数缓冲区的大小 内存计算公式 (简化):

额外内存 ≈ max_num_seqs × (

max_model_len × 4 + # prefill_token_ids 各种状态缓冲区大小 )

2. 调度性能 正面影响 : 吞吐量 : 较大的

max_num_seqs

允许更多请求并发处理,可能提高吞吐量 GPU 利用率 : 更多请求可以更好地利用 GPU 的并行计算能力 负面影响 : 延迟 : 如果

max_num_seqs

太小,请求会在等待队列中停留更长时间 内存压力 : 更大的

max_num_seqs

需要更多 GPU 内存 3. 并发处理能力 限制因素 : 如果实际并发请求数 >

max_num_seqs × data_parallel_size

,多余的请求会排队等待 等待时间会被计入性能指标(TTFT、TPOT),影响用户体验 4. 批处理效率 批处理大小 : 每次推理步骤最多处理

max_num_seqs

个请求 如果请求数 <

max_num_seqs

,批处理可能不够满,GPU 利用率可能下降 如果请求数 >

max_num_seqs

,需要多步处理,可能增加延迟 四、使用建议 1. 根据硬件资源调整 GPU 内存充足时 : 可以设置较大的

max_num_seqs

(如 256、512) 提高并发处理能力和吞吐量 GPU 内存受限时 : 需要减小

max_num_seqs

(如 64、32) 避免 OOM(Out of Memory)错误 2. 根据工作负载调整 高并发场景 : 确保

max_num_seqs × data_parallel_size >= 预期并发数

避免请求长时间等待 低延迟优先场景 : 可以适当减小

max_num_seqs

减少批处理大小,降低单步处理时间 高吞吐量优先场景 : 增大

max_num_seqs

提高批处理效率 3. 与 max_num_batched_tokens 的平衡 经验法则 :

max_num_batched_tokens

应该 >=

max_num_seqs

对于短序列请求,可以设置

max_num_batched_tokens

远大于

max_num_seqs

对于长序列请求,需要确保

max_num_batched_tokens

足够大以处理长序列 4. 数据并行场景 重要公式 :

总并发能力 = max_num_seqs × data_parallel_size

建议 : 在设置

max_num_seqs

时,考虑

data_parallel_size

确保总并发能力满足实际需求 五、代码示例 1. 在 vLLM 中设置

from vllm import LLM

llm = LLM( model="your-model", max_num_seqs=128, # 设置最大序列数 max_num_batched_tokens=2048, # 必须 >= max_num_seqs )

2. 在 vLLM-Ascend 中设置

vllm serve Qwen/Qwen3-VL-235B-A22B-Instruct \

--max-num-seqs 16 \ --data-parallel-size 2 \ --max-num-batched-tokens 4096 \ ...

3. 验证配置

# 在 SchedulerConfig 中会自动验证

# 如果 max_num_batched_tokens < max_num_seqs,会抛出 ValueError

六、常见问题 Q1: max_num_seqs 设置太小会怎样?

A : 请求会在等待队列中停留更长时间 吞吐量下降 延迟增加(等待时间计入 TTFT/TPOT) Q2: max_num_seqs 设置太大会怎样?

A : GPU 内存占用增加 可能导致 OOM 批处理效率可能下降(如果实际请求数远小于 max_num_seqs) Q3: 如何确定合适的 max_num_seqs?

A : 根据 GPU 内存容量估算 根据实际并发需求计算:

max_num_seqs × data_parallel_size >= 并发数

通过性能测试找到最佳平衡点 Q4: max_num_seqs 和 max_num_batched_tokens 的区别?

A :

max_num_seqs

: 限制 请求数量

max_num_batched_tokens

: 限制 token 数量 两者共同决定批处理能力 七、总结

max_num_seqs

是 vLLM 中一个关键的调度和资源管理参数,它: 限制并发 : 控制同时处理的请求数量 分配内存 : 决定各种缓冲区的分配大小 影响性能 : 直接影响吞吐量、延迟和 GPU 利用率 与 DP 相关 : 在数据并行场景下,总并发能力 =

max_num_seqs × data_parallel_size

合理设置

max_num_seqs

需要在 内存占用 、 并发能力 和 性能指标 之间找到平衡点。

相关文章