跳转到内容

输入关键词开始搜索

    资料摘要:personal chatgpt 20 — llama2 源码分析 cache KV(keys、values cache)加速推理

    视频摘要更新 2026-08-02置信度 high待阅读原始来源 ↗#深度#大模型#课程#personal-chatgpt

    本讲由真实视频转录与作者 notebook/代码交叉整理。原始层:🔒 带时间戳视频转录;课程总览:personal chatgpt — LLMs 实践系列

    KV Cache 用于 decoder 的自回归生成:每个新 token 只重新计算自己的 Q/K/V,把新 K/V 追加到缓存,并复用所有历史 K/V。这样避免每一步都重新对整个前缀做 K/V 投影。课程结合 Llama 2 Attention 源码追踪缓存张量和 start_pos,再用 GPT-2 对比 use_cache=True/False 的生成耗时。

    生成第一个 token 时要处理完整 prompt;之后每一步把上一步输出追加到输入。当前 token 的 query 必须与全部历史 keys 做注意力,并对历史 values 加权。如果每步把完整前缀再次输入而不缓存,历史 token 的 K/V 投影会被反复计算。

    KV Cache 只用于生成/decoder 阶段。课程举例:GPT 这类 decoder-only 模型支持;T5 在 decoder 部分使用;BERT 这类非生成 encoder-only 模型没有这种逐 token 解码缓存。

    增量解码时,当前 Q 可以只对应最新 token,而 K/V 必须覆盖当前 token 与全部历史 token。因此课程把当前 Q 描述为 vector,把累积 K/V 描述为沿 sequence 维增长的 matrices。

    Attention.__init__[max_batch_size, max_seq_len, n_kv_heads, head_dim] 预分配 cache_k/cache_v。每次 forward 用 start_pos:start_pos+seqlen 写入新 K/V,再读取 :start_pos+seqlen 的全部历史缓存。

    首轮 prompt 可能一次写入多个 token;后续循环通常 token-by-token。课程示例 prompt 有 8 个 token,最大新生成 64 个 token,因此生成循环上界为 72。

    Notebook 对 use_cache=True/False 各执行 10 次、每次最多生成 1,000 个新 token。保存输出为:

    • with KV caching: 6.636 ± 0.023 s
    • without KV caching: 8.283 ± 0.049 s

    这是特定 GPU、GPT-2、prompt 和生成长度下的结果,只证明该环境中的差异,不能直接外推到其他模型或 batch。

    Attention(Q,K,V)=softmax(QKTdk)V\operatorname{Attention}(Q,K,V)= \operatorname{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V

    self.cache_k[:bsz, start_pos:start_pos + seqlen] = xk
    self.cache_v[:bsz, start_pos:start_pos + seqlen] = xv
    keys = self.cache_k[:bsz, :start_pos + seqlen]
    values = self.cache_v[:bsz, :start_pos + seqlen]
    for use_cache in (True, False):
    model.generate(
    **tokenizer("What is KV caching?", return_tensors="pt").to(device),
    use_cache=use_cache,
    max_new_tokens=1000,
    )

    更准确的复杂度边界是:KV Cache 消除了历史 token 的重复 K/V 投影,但生成第 tt 个 token 时,新 Q 与 tt 个历史 K 的点积仍是 O(t)O(t);它不是让 attention 对上下文长度变成常数时间。

    时间 内容
    00:00 引入 KV Cache 与推理加速
    01:00 K/V 指 scaled dot-product attention 中的 Key/Value
    02:00 只在 decoder/生成过程使用;BERT 不适用
    03:32 SOS、EOS 与逐 token 自回归
    05:00 不缓存时长前缀带来的重复计算
    06:08 新 token 计算 Q/K/V,仍需历史 K/V
    07:59 图示无缓存与有缓存的差异
    09:00 跟踪 Llama 2 生成循环与首轮 prompt
    12:00 cache_k/cache_v 沿 sequence 维写入与读取
    13:47 GPT-2 基准:约 6.6 秒对 8.3 秒
    • 运行标签:conditional / source-bundle not-as-written。 需要 CUDA、Transformers、PyTorch、SentencePiece、网络下载 GPT-2,并执行 20 次长生成。
    • source_bundle/code/lesson_20 缺少 6 张相对图片和 ./tokenizer.model;主仓库 imgs/tutorials/tokenizer.model 存在。
    • Llama Attention 代码位于 Markdown 代码块,依赖 ModelArgs、并行线性层等完整仓库上下文,不能单独复制即运行。
    • 基准硬编码 device="cuda",每次 max_new_tokens=1000,运行成本较高。
    • 本次没有重跑基准;数值来自 Notebook 保存输出,转录约 13:47–13:54 也口述“6 秒/8 秒”。
    • 承接第 18、19 讲: Q/K 先应用 RoPE,随后 K 与 V 写入缓存;缓存中保存的是已投影、已处理位置的状态。
    • 总结第 15–20 讲源码线: 从推理入口、block 组件、RoPE 到增量解码缓存,形成一条完整的 Llama 2 推理阅读路径。
    • 后续延伸边界: 本讲没有讲 PagedAttention、GQA/MQA 或 KV 量化,不应按标题自行补入。
    1. KV Cache 避免了哪些重复计算,又没有消除哪些计算?
    2. 为什么增量解码时当前 Q 可以只对应新 token,而 K/V 要覆盖整个前缀?
    3. start_pos 在写入和读取缓存时分别起什么作用?
    4. 为什么 BERT 不使用本讲所说的生成式 KV Cache?
    5. 课程的 6.636 秒与 8.283 秒基准为什么不能直接推广到 Llama 2 70B?
    • 滴答清单抓取时学习状态:已完成
    • 视频正文采用自动语音识别;关键术语已用标题、notebook 与源码校正,无法确认的口语细节不扩写。
    • notebook 未执行的 CUDA、权重下载、训练或外部 API 单元,不表述为已复现实验。