共享前缀、并行采样、束搜索 有什么区别?
场景本质多个不同用户请求共享“服务端提前定义的公共前缀”(如翻译任务中,所有用户请求的prompt都包含“Translate English to French: 示例1→示例2→示例3”,用户仅需输入私有内容如“cheese”)。共享逻辑前缀是“服务端预生成的公共内容”(非用户输入的prompt),在不同用户请求间共享——服务端提前计算公共前缀的KV缓存并存储到物理Block中,所有包含该前缀的
·
你的观察很敏锐——三者确实都涉及“前缀共享”,但在共享对象的来源、共享范围、生命周期和适用场景上存在本质差异,核心是“前缀由谁生成、能被多少请求共享、是否随解码动态变化”。结合论文4.4小节及6.3-6.4小节的细节,具体区别如下:
一、核心差异总览:从“共享三要素”切入
为清晰区分,先定义“共享三要素”——前缀来源(谁生成的前缀)、共享范围(多少请求/序列能共享)、生命周期(共享关系是否随解码变化),三者的差异如下表所示:
| 特征维度 | 并行采样(Parallel Sampling) | 束搜索(Beam Search) | 共享前缀(Shared Prefix) |
|---|---|---|---|
| 前缀来源 | 单个用户请求的输入prompt | 单个用户请求的输入prompt + 已生成的候选前缀 | 服务端预定义的公共前缀(如任务指令、示例) |
| 共享范围 | 同一请求内的多个输出候选序列 | 同一请求内的多个候选序列 | 不同用户请求之间(跨请求共享) |
| 生命周期 | 固定(仅prompt部分共享,生成阶段无新增共享) | 动态(随解码推进,候选淘汰/新增,共享关系实时变化) | 固定(前缀由服务端预生成,不随请求解码变化) |
| 核心目标 | 减少同一请求内的prompt KV缓存冗余 | 减少同一请求内候选序列的前缀冗余 | 减少不同请求间的公共前缀计算与存储冗余 |
| 论文示例/实验场景 | 代码助手为1个prompt生成3种代码建议 | 机器翻译为1个输入保留top-4候选翻译 | 翻译任务中,所有请求共享“指令+5个翻译示例”的前缀 |
二、逐一拆解:从“场景+共享逻辑”看差异
1. 并行采样(Parallel Sampling):同一请求内的“固定prompt前缀共享”
- 场景本质:为单个用户请求的1个输入prompt,生成多个独立的输出候选(如用户输入“写一段请假条”,模型生成3版不同表述)。
- 共享逻辑:
- 前缀是“用户输入的prompt”(如“写一段请假条”对应的KV缓存),仅在同一请求内的多个候选序列间共享——所有候选的prompt完全相同,因此它们的“prompt对应的KV Block”映射到同一个物理Block(引用计数=候选数);
- 共享关系固定不变:生成阶段,各候选会生成不同的输出token,此时不再新增共享(仅在prompt阶段共享),若需修改共享Block(如填充新token),则通过“写时复制”分配新Block(避免影响其他候选);
- 论文实验(6.3小节):并行采样的内存节省主要来自“prompt部分的共享”,节省比例为6.1%-30.5%(ShareGPT数据集因prompt更长,节省比例更高)。
2. 束搜索(Beam Search):同一请求内的“动态候选前缀共享”
- 场景本质:为单个用户请求的1个输入prompt,生成“概率最高的top-k个候选序列”(如机器翻译输入“Hello”,保留top-4最可能的法语翻译),候选序列会随解码实时淘汰/保留。
- 共享逻辑:
- 前缀包含“用户输入的prompt”和“候选序列已生成的公共部分”——不仅共享prompt,还共享候选序列在解码过程中产生的公共前缀(如候选1“Bonjour le”、候选2“Bonjour la”,共享“Bonjour”前缀);
- 共享关系动态变化:每轮解码后,若部分候选被淘汰(不再是top-k),其独占的KV Block会被释放,剩余候选的共享范围可能扩大或缩小(如图9中,淘汰候选0和3后,候选1-2的共享Block从3个增加到4个);
- 核心区别于并行采样:并行采样的共享仅局限于“固定prompt”,束搜索的共享则延伸到“动态生成的候选前缀”,且共享范围随解码推进实时调整,内存节省比例更高(37.6%-66.3%,6.3小节)。
3. 共享前缀(Shared Prefix):跨请求的“服务端预定义前缀共享”
- 场景本质:多个不同用户请求共享“服务端提前定义的公共前缀”(如翻译任务中,所有用户请求的prompt都包含“Translate English to French: 示例1→示例2→示例3”,用户仅需输入私有内容如“cheese”)。
- 共享逻辑:
- 前缀是“服务端预生成的公共内容”(非用户输入的prompt),在不同用户请求间共享——服务端提前计算公共前缀的KV缓存并存储到物理Block中,所有包含该前缀的用户请求,其“前缀对应的逻辑Block”直接映射到预缓存的物理Block(无需重复计算);
- 共享关系全局固定:公共前缀由服务端预先定义(如1-shot/5-shot示例),不随用户请求的解码变化,用户请求仅需计算“私有内容”的KV缓存(如“cheese”对应的Block);
- 核心区别于前两者:前两者是“同一请求内的序列共享”,而共享前缀是“跨请求的全局共享”,前缀由服务端统一生成,而非用户请求的输入,能减少大量不同请求的重复计算与存储(论文6.4小节实验:5-shot前缀场景下,vLLM吞吐量是Orca(Oracle)的3.58倍)。
三、一句话总结核心差异
- 并行采样:同一请求内的多个候选,共享“用户输入的固定prompt前缀”;
- 束搜索:同一请求内的多个候选,共享“prompt+动态生成的候选公共前缀”(共享范围随解码变);
- 共享前缀:多个不同请求,共享“服务端预定义的公共前缀”(跨请求、全局共享)。
三者的“共享前缀”看似相似,但共享的“主体”“范围”和“灵活性”完全不同,分别对应LLM服务中“单请求多候选”和“多请求公共前缀”两类不同场景的内存优化需求。
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)