大模型推理基础
自回归生成原理
大语言模型的文本生成过程分为两个核心阶段:
-
预填充(Prefill)阶段:以并行方式处理输入提示中的所有词元,一次性计算出所有输入词元的Key和Value,并缓存起来。
-
解码(Decoding)阶段:文本会以自回归的方式逐个生成词元。每个生成的词元都会被添加到输入中,并重新喂入模型,以生成下一个词元。当模型输出了特殊的停止词元或满足用户定义的条件(例如生成了最大数量的词元)时,生成过程就会停止。
自回归生成的本质是:每一步只预测下一个词元的概率分布,基于已生成的序列继续生成。这虽然保证了生成的灵活性,但也带来了推理效率的挑战。
常用解码策略
Greedy Search(贪心搜索)
- 每一步选择概率最高的词元作为下一个词
- 优点:计算简单,速度快
- 缺点:容易陷入局部最优,容易产生重复,生成质量不高
Beam Search(束搜索)
- 每一步保留概率最高的k个候选序列(k为beam size)
- 在最后一步从k个候选中选择整体概率最高的序列
- 优点:比贪心搜索生成质量更高
- 缺点:计算量较大,内存占用高,仍然可能出现重复
Sampling(采样)
根据概率分布随机采样下一个词,而不是总是选择概率最高的。这样可以增加生成的多样性,常见的优化包括:
Temperature(温度)
- 对原始概率分布进行重缩放:Pi=∑jelogitj/Telogiti/T
- T < 1:概率分布变得更尖锐,高概率词更可能被选中,生成更确定
- T > 1:概率分布变得更平滑,低概率词也有机会被选中,生成更多样
- 经验调参:
- 需要复现训练集效果:temperature = 0.01
- 需要多样输出:temperature = 0.8 ~ 1.2
Top-k Sampling
- 只从概率最高的k个词中采样
- 缺点:当概率分布比较平坦(很多词概率接近)时,会过滤掉一些有价值的低概率词;当分布非常尖锐(少数几个词概率很高)时,会引入不必要的噪声词
Top-p Sampling(Nucleus Sampling)
- 选择最小的一组词,它们的累积概率超过p(比如p=0.9)
- 只从这组词中采样
- 优点:根据概率分布自适应调整候选集大小,概率尖锐时候选集小,概率平坦时候选集大
- 通常p设置为0.8 ~ 0.95
生成参数调参建议
1# 典型参数设置
2do_sample=True, # 启用采样,否则使用贪心或beam search
3temperature=1.0, # 控制多样性
4top_p=0.9, # Nucleus采样阈值
5repetition_penalty=1.8, # 对已出现词的惩罚,减少重复
6no_repeat_ngram_size=6, # 禁止n-gram重复
7max_new_tokens=200 # 最大生成长度
调参经验:
- 生成结果有重复:调高repetition_penalty
- 生成单一,不够多样:调高temperature,调高top_p
- 需要稳定复现:调低temperature(接近0)
- 具体效果需要根据任务而定,没有固定参数
推理性能衡量指标
要准确衡量模型的推理速度,需要关注以下几个核心指标:
-
首个词元生成时间(Time To First Token, TTFT)
- 用户输入查询后,模型生成第一个输出所需的时间
- 在实时交互中,低TTFT非常重要,直接影响用户体验
- 离线任务中不太重要
-
单个输出词元的生成时间(Time Per Output Token, TPOT)
- 每个用户生成一个输出词元所需的平均时间
- TPOT 100ms/token表示每秒可处理10个词元,每分钟约450个词,超过普通人阅读速度
-
端到端时延
- 模型为用户生成完整响应所需的总时间
- 时延 = TTFT + TPOT × 待生成的词元数
-
吞吐量
- 推理服务器在所有用户和请求中每秒可生成的输出词元数
- 高吞吐量意味着能同时服务更多用户
权衡要点:
- 目标:最短TTFT、最高吞吐量、最短TPOT
- 需要权衡吞吐量和每个词元的延迟:同时处理16个用户查询,吞吐量会更高,但每个用户的TPOT会变长
推理时延启发式评估
- 输出长度决定整体响应时延:平均时延 ≈ 预期输出词元长度 × 平均TPOT
- 输入长度对性能影响较小,但对硬件要求高:添加512个输入词元增加的时延,通常少于生成8个额外输出词元的时延,但支持长输入需要更大显存
- 整体时延与模型大小呈次线性关系:相同硬件上,模型越大速度越慢,但速度比不一定等于参数数量比。例如:MPT-30B时延约为MPT-7B的2.5倍,LLaMA2-70B时延约为LLaMA2-13B的2倍。
推理效率瓶颈分析
大模型推理的主要瓶颈包括:
- 内存带宽瓶颈:大模型参数多,每次解码都需要从显存/内存读取所有参数,计算密度低,IO成为瓶颈
- KV缓存内存占用:每个序列的Key和Value都需要缓存,序列越长,占用越大,容易占满显存
- 动态序列长度:不同请求的序列长度变化很大,导致内存碎片化,降低利用率
- 批处理效率:传统静态批处理需要等所有序列生成完才能下一批,GPU利用率低
常见推理速度对比
- 7B量级模型:CPU推理约10 token/s,单卡A6000约100+ token/s,GPU:CPU速度比约10:1
- INT8 vs FP16:在HuggingFace实现中,INT8推理通常明显慢于FP16,但显存占用小很多
面试常见问题
Q1: 大模型生成为什么是自回归的?
A: 因为大语言模型训练时就是下一个词元预测任务,每个位置只预测下一个词元。这种设计简单且有效,能够处理任意长度的序列生成,这是目前大语言模型最主流的生成方式。
Q2: Temperature是如何影响生成结果的?Temperature=0会怎么样?
A: Temperature通过重缩放概率分布来控制生成的随机性。T越小,高概率词更可能被选中,生成越确定;T越大,分布越平坦,更多样。Temperature=0退化为贪心搜索,总是选概率最高的词,生成最确定但也最容易重复。
Q3: Top-k和Top-p有什么区别?可以同时使用吗?
A: Top-k固定从k个最高概率词中采样,候选集大小固定;Top-p根据累积概率动态调整候选集大小,适应不同的概率分布。两者可以同时使用,先用Top-p过滤,再从结果中Top-k采样,进一步控制多样性。
Q4: 如何减少大模型生成的重复?
A: 常用方法包括:设置repetition_penalty对已出现词降低概率;使用no_repeat_ngram_size禁止n-gram重复;调整temperature降低随机性;使用更优的解码策略如beam search。
Q5: 为什么大模型推理时显存占用一直很高?
A: 主要有两个原因:1) 模型参数本身需要加载到显存,FP16下nB模型需要2nGB显存;2) 每个推理请求都需要缓存Key和Value(KV Cache),序列越长,并发请求越多,KV Cache占用越大,这些显存需要一直保留给推理使用。
Q6: 如何提高推理吞吐量?
A: 主要方法包括:使用更好的KV缓存管理(如PagedAttention);使用连续批处理(Continuous Batching)动态加入新请求;量化压缩模型参数;使用专门的推理优化框架(vLLM、Text Generation Inference等);张量并行多GPU分摊。