大模型批量(Batch)推理
2025-07-09 本文已影响0人
梅西爱骑车
一、传统批量(Batch)推理
在(vLLM等推理框架采用的)Continuous Batching之前,传统的大模型推理batch实现方式主要涉及数据预处理、模型输入构建以及推理执行等几个关键步骤:
1.1 数据预处理
- 分词:将输入的文本数据(如用户的问题、待翻译的句子等)按照模型特定的分词器进行处理。例如,对于基于Transformer架构的模型,像BERT、GPT系列等,会将文本切分成一个个的token(可以是单词、子词等)。假设输入文本是 “I love natural language processing”,经过分词后可能得到 ["I", "love", "natural", "language", "processing"] 这样的token序列 。
- 转换为ID:将分好的词映射为模型能够处理的数字ID。每个token在模型的词表中都有唯一对应的ID,模型通过这些ID来理解和处理文本信息。比如,"I" 的ID可能是100,"love" 的ID是200 等。
- Padding(填充):由于一个batch中各个输入样本的长度往往不同,为了能够在模型中进行并行计算,需要将所有样本填充到相同的长度。通常是将短的序列后面填充特殊的padding token(其ID也是固定的),使其长度与该batch中最长的序列一致。比如一个batch中有两个样本,分别是 ["I", "love", "you"] 和 ["I", "like", "natural", "language", "processing"],假设最长序列长度为5,那么第一个样本就会被填充为 ["I", "love", "you", padding_token, padding_token]。
1.2 构建模型输入
- 整理成张量:将经过预处理后的ID序列整理成张量(Tensor)形式,常见的是多维数组,如二维数组(batch_size, sequence_length),batch_size表示一个batch中的样本数量,sequence_length表示填充后的序列长度。例如,一个batch中有3个样本,填充后的序列长度都是10,那么就会得到一个形状为 (3, 10) 的张量 。
- 添加其他辅助信息:除了文本ID序列,还可能需要添加一些辅助信息,如注意力掩码(Attention Mask),用于告诉模型哪些位置是有效的token,哪些是padding token,以便在计算注意力机制时忽略padding部分;以及位置编码(Position Embedding),用来让模型感知文本中token的位置信息。
1.3 推理执行
- 送入模型:将构建好的输入张量传入大模型中,模型根据自身的参数和架构对输入进行计算。以Transformer模型为例,会经过多层的自注意力机制和前馈神经网络等模块,逐步对输入进行特征提取和语义理解。
- 获取输出:模型计算完成后,会输出相应的结果,如文本生成任务中会输出下一个token的概率分布,然后根据一定的策略(如贪心搜索、beam search等)从概率分布中选取合适的token,生成最终的输出文本。
在这个传统batch推理过程中,padding虽然使得并行计算成为可能,但也带来了内存占用和计算资源浪费的问题,尤其是在不同样本长度差异较大时,很多计算都是在处理padding部分,这也正是Continuous Batching等优化技术出现的原因,它们旨在提高batch推理的效率,减少这种不必要的资源消耗。
二、连续批处理Continuous Batching
这段文字在讲解大模型推理场景里 “Continuous Batching(连续批处理 )” 优化 Padding 问题 的原理,核心是解决多批次推理时因序列长度差异导致的资源浪费和耗时问题,拆解理解如下:
2.1 先看 “多 batch 推理的 Padding 问题”
- 场景:大模型做批量推理时(比如同时处理 10 条用户请求),这些请求的序列长度(可理解为文本字数、token 数量)不一样,比如有的短序列生成完了,长序列还在生成。
- 传统处理:为了统一计算,会给短序列 “补 padding(填充无意义内容 )”,强行把所有序列凑成一样长 。
- 问题:这些 padding 既占内存(存无意义数据),又占生成时间(模型得算这些无效填充)。
2.2 再看 “Continuous Batching 的优化逻辑”
“把新的 sequence 填充到短 sequence 后面”,意思是:
- 不强行等所有序列统一长度,短序列生成完就释放位置,直接把新的推理任务(新 sequence )填到空出来的位置里继续算。
- 这样就不用一直等长序列拖时间,也不用存大量无意义 padding,相当于动态利用计算资源,自然能缩短整体生成时间。
2.3 举个简单例子
-
传统方式:
同时推理 3 条序列,长度是[20, 50, 100],为了统一,全补到 100 长度,推理时模型要算 100 长度 ×3 条,其中前两条后面 80、50 个 padding 都是无效计算,还得等最长的 100 长度跑完才能结束。 -
Continuous Batching 优化后:
短序列(20、50 长度)生成完,直接把新的序列(比如又来两条新请求)填到它们的位置,继续推理,不用等 100 长度跑完再处理新任务,也少了大量 padding 计算,整体耗时就缩短了。
vLLM官方的一个例子
# 这个例子来自于vLLM官方
from vllm import LLM, SamplingParams
prompts = [
"Hello, my name is",
"The president of the United States is",
"The capital of France is",
"The future of AI is",
]
sampling_params = SamplingParams(temperature=0.8, top_p=0.95)
llm = LLM(model="Qwen/Qwen2.5-1.5B-Instruct")
outputs = llm.generate(prompts, sampling_params)
for output in outputs:
prompt = output.prompt
generated_text = output.outputs[0].text
print(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")
简单说,Continuous Batching 就是通过 动态复用短序列空出的资源,减少无效 padding 的内存、时间消耗,让推理更高效,尤其在多批次、序列长度差异大的场景里,能显著提升模型推理速度。