Lookahead Cache

最近更新时间:2025-08-04 10:53:21

我的收藏

默认方式开启

您只需在启动命令行中加入以下命令,即可开启 lookahead-cache:
--lookahead-cache-config-dir ./ # 或者任意其他目录
如果您只想了解 LookaheadCache 在默认配置下的加速效果(默认配置通常已足够优秀),那么以上便是您需要知道的所有信息。如果您希望进一步调整性能,选择不同的 CacheMode,或查看 debug log 等,那么您需要继续阅读后续内容。

基本原理

一句话概括 Lookahead Cache 的基本原理:使用历史的 Token 对(key: value)来预测当前 Token 对的 value 值。所提及的 Lookahead Cache 是 Taco-LLM完全自主研发的 Lookahead 技术,主要设计并实现了两个基础方案。下图展示了第一个方案的 Lookahead Cache:

方案一的 Lookahead Cache 参见了LLMA 和 N-gram 的设计思想,并在此基础上进一步优化,并增加了新特性。
主要特点是:
支持变长的 Lookahead Len;
支持 batch 化;
支持变长 cuda-graph。
方案二抛弃了 N-gram 和 LLMA 的设计思想,重新设计,相比方案一继承了其所有优点,同时拥有更加高的平均命中长度,但是也更加复杂,这里不详细叙述。
在功能上,方案二新增支持:
Multi-path 的多候选结果输出;
基于前缀树的多候选结果的输出;
树的动态裁剪;整体上的预测结果命中率是方案一的1.4x,部分场景是方案一的2.0x。
但是相比方案一,方案二的冷启动问题更加明显,所以往往结合方案一一起使用。

进阶使用方式

配置介绍

在这种使用方式下,您需要提供一个命名为 lookahead_cache_config.json 的配置文件,该文件必须位于通过 --lookahead-cache-config-dir 指定的目录中。(文件名: lookahead_cache_config.json)
{
"cache_mode": 2,
"cache_size": 5000000,
"copy_length": 7,
"match_length": 2,
"turbo_match_length": 7,
"min_match_length": 2,
"cell_max_size": 16,
"voc_size": 200000,
"max_seq_len": 32768,
"eos_token_id": 2,
"top_k": 1,
"threshold": 2.0,
"decay": 0.5,
"is_hybrid": true,
"is_debug": true,
"log_interval": 3000,
"target_parallelism": 512,
"top_k_in_cell": 16,
"token_paths_top_k": 2,
"start_freq": 10.0,
"num_threads": 8,
"global_cache_switch": true
}
还有选择性的 warmup_file 配置。
参数
参数解释
cache_mode
0表示 RawLookaheadCache(第一版),1 表示 TurboLookaheadCache(第二版),2表示两者混合的方式,混合方式:在 TurboLookaheadCache 返回结果为空时,使用 RawLookaheadCache 来预测,RawLookahead 的命中率更低,但是在开始阶段的触发概率更高,而 TurboLookaheadCache 的 warmup 的时间稍长,在测试数据很少的时候,建议 cache_mode设置为2,如果有充足的测试数据,建议设置 cache_mode 为1,因为其命中率和准确率在大部分场景下都更好,有更少的冗余计算。
cache_size
cache 的大小,可以不用设置,而通过 taco-llm 的命令行参数 --cpu-decoding-memory-utilization 来设置。它是一个0到1的值,表示使用当前环境下内存的比值,默认是0.15。
copy_length
lookahead 往前看的长度。
match_length
触发 lookahead cache 的匹配长度。
turbo_match_length
TurboLookaheadCache 的最大匹配长度。
min_match_length
TurboLookaheadCache 的最小匹配长度。
cell_max_size
二级缓存的大小,同一个匹配下不同词组,按照出现频率和时间,组成一个 LRU的cache。
voc_size
tokenizer 中词表的大小。
max_seq_len
模型的最大序列长度,不用配置,直接可以从模型的 config 中获取。
eos_token_id
结束 token,不用配置,直接从模型的 config 文件中获取。
top_k
取二级 cache 频率最大,时间最近的词的数目。
threshold
二级 cache 满了以后,需要删除时,要删除对象的频率阈值。
decay
对于二级 cache 满了时,且所有的频率都高于 threshold 时,需要先衰减。
is_hybrid
针对 RawLookaheadCache 打开,多种 match-length 会结合,例如,match-length=3时,会混合 match-length=3,2,1。
is_debug
打开时,会输出 cache log。
log_interval
打印 log 的频次。
target_parallelism
最大并行度,即 sum(seq_lens),开启了这个就会,在 sum(seq_lens) > target_parallelism 后会根据各个 seq 的命中情况来惩罚 copy_length。仅仅对 cache_mode=0 时有效。
top_k_in_cell
仅针对 TurboLookaheadCache,表示查找二级缓存时,一次返回 token 的数目。
token_paths_top_k
表示 beam search 的宽度,默认是1,在命中率比较低时,可以尝试把这个参数改为2,或者更大,建议在4以内。这个参数的开启在一定程度上增加了命中率,同时也会增加冗余计算。
start_freq
表示 local cache 的初始比重,越高表示优先保留 Local cache 中得到的 path,仅在 token_paths_top_k>1 时生效。
num_threads
表示在使用 TurboLookaheadCache 的并发度,提升的是 TurboLookaheadCache 本身的运行速度。
global_cache_switch
为 True 表示开启 global_cache,false 表示关闭,这样样本之间将不受影响。
ignore_prompt
忽略 prompt,多针对翻译等 prompt 和 generation tokens 毫无关系的场景。

注意的问题

ignore_eos

正确操作:ignore_eos=False
在测试 taco_llm lookahead 时,这个参数需要设置为 False,因为 LookaheadCache 里,遇到 eos 的 token_id 时,会把 local_cache 清除掉。将会影响hit_rate 和 global_average_hit_len 等指标,最终影响整体的性能。如果需要测试固定的输出长度,建议在搜索样本时,选择更长的输出样本,然后把output_len 固定,这样可以减少 output tokens 未到目标输出长度时,就遇到 eos token。

常用性能调节方式

注意:
以下的配置方式可以叠加使用。

小数据集测试

如果发现使用少量样本测试,TurboLookaheadCache(cache_mode=1)效果比 RawLookaheadCache(cache_mode=0)的性能还要差,此时建议用cache_mode=2的混合模式。增加如下配置:
{
"cache_mode": 2
}
这是由于 TurboLookaheadCache 的冷启动问题导致的。

性能不符合预期

现象:使用 lookahead-cache 默认配置会有1.7x-3.x+的性能收益,如果没有达到这个收益。首先需要查看是否使用了 greedy 的采样方式(这样会有最好的性能)。如果因为业务的原因不能使用 greedy,可以在满足业务需要的情况下调小 temprature,尽可能的减少随机性。这样调节和 lookahead cache 的原理密切相关。lookahead cache 会将历史输入和输出的 tokens 都存放到 cache 中,如果输出的随机性太强,那么历史输入对当前输出的参考性,就会变弱,从而导致 cache 的命中率下降,加速性能也下降。
在上述配置都没有问题的情况下,依然不符合加速预期,可以在 lookahead cache 的配置目录下,增加含有如下内容的配置文件(文件名: lookahead_cache_config.json):
{
"is_debug": true,
"log_interval": 300
}
添加此配置后,系统将输出 hit-rate 的相关指标,如下图所示。




各命中率指标的含义

num_iters: 平均每一个请求的 generation 阶段的自回归次数。
hit_iters:平均每一个请求的命中长度大于0的迭代次数。
hit_len:平均每一个请求的命中总长度。
invalid_len: 平均每一个请求 lookahead 的总长度减去命中的总长度: lookahead_len - hit_len。
hit_rate: 平均每一个请求命中的迭代次数除以总自回归次数: hit_iters / num_iters。
global_average_hit_len: 平均每一个请求的平均每次迭代的命中长度: hit_len / num_iters。
valid_average_hit_len: 平均每一个请求命中长度大于0的情况下,平均命中长度:hit_len / hit_iters。
hit_valid_rate: 平均每一个请求在总的命中长度除以总的 lookahead 长度:hit_len/ lookahead_len。
其中 global_average_hit_len 加1,即表示开启 lookahead 下,每一次 decoding 迭代平均吐出的 token 数目,理想情况下,这个数据表示 decoding 过程的加速倍数。例如上图所示,global_average_hit_len = 1.59,加1为2.59,那么理想情况下 decoding 阶段加速2.59倍。hit_rate 表示至少有一个命中的命中次数与全局迭代次数的比值。valid_average_hit_len 表示如果至少有一个 token 命中的情况下。平均的命中长度,这个数据加1,可以用来调节 copy_length 的大小,注意:如果使用了 mutli-path 优化,不能使用这个方式来调节。下面举例说明在采样方式没有问题时,如何调节 Lookahead Cache。

指标 global_average_hit_len<0.8

当 global_average_hit_len < 0.8 时,属于命中长度较低的情况。首先,确认是否开启了 MultiPath 功能。如果使用的是默认配置,即没有指定配置文件或者 cache_mode 项未进行配置,那么可以确定 MultiPath 已开启,且其值为 2。如果未开启,可添加以下配置:
{
"is_debug": true,
"log_interval": 3000,
"token_paths_top_k": 2,
"start_freq": 10.0
}
添加该配置后,会禁用并行度惩罚。因此,在大批量处理(>=64)时,冗余计算可能会显著增加,这可能会影响性能。如果性能下降是由此原因引起的,可以尝试降低 copy_length 的值。如果这些操作都无效,请检查 ignore_eos 是否设置为 False(如上文所述)。
确定 MultiPath 生效,但是 global_average_hit_len 依然较低,可以尝试增加路径的数量,即调整 token_paths_top_k 的设置。token_paths_top_k 的设定可以采用 copy_length / valid_average_hit_len 的方法,其中默认的 copy_length 为7。
如果此时 global_average_hit_len 指标仍然不高(<0.8),则需要检查测试场景,例如生成序列长度很短(<=32),或者输入和输出为语音、多模态等毫无关联的场景。在这种情况下,Lookahead Cache 在原理上受限,不会有很好的效果。

指标 global_average_hit_len>=0.6 && <=1 性能差

global_average_hit_len 在 [0.6, 1] 这个区间内,但是端到端的速度甚至没有提升,可以尝试以下操作:
大 batchsize(>=32),此时冗余计算会比较多,lookahead 带来的收益可能不足以抵消冗余计算带来的开销,可以试着调低 copy_length,可以4,5,6分别尝试,如果测试数据足够,也是尝试将 cache_mode 修改为1,将 copy_length 调节到2,3等。
低算力卡(HCCPNV6, PNV6, PNV5b): 分析和调节方法与大 batchsize 场景类似,此时该问题可能会来的更早,例如 bs=16左右。

不同的样本请求差别较大时

不同的样本之间差别较大时,需要快速的更新 cache,增加时间局部性,可以尝试增加下面的一组调节参数。也可以通过 cell_max_size 指标的调节来改变cache 的变化速度,其值越小变化的越快,默认值是16,建议的调节范围是[8, 32].
{
"start_freq": 1.0,
"decay": 0.1,
"cell_max_size": 16
}

warmup

文件格式为 JSON 格式,数据格式为 [{"prompt": [token_ids], "output": [token_ids]}]。处理后,将其路径设置到 lookahead_cache_config.json 中,字段名为 "warmup_file":warmup_file_path。