序列模型与Transformer
KV 缓存(KV cache)
/ kay-vee kash /
KV 缓存,是一条省内存的捷径,它让文本生成变快。当模型一次写一个词元时,每个新词元都要回头注意已生成的每一个词元——而这需要那些较早词元的键向量与值向量。天真的做法是为每一个新词都从头重算它们,这极其浪费。KV 缓存索性把它们记下来:每个词元的键与值只算一次,存起来,在余下的生成里反复取用。
回报是惊人的。没有缓存,生成第一百个词元意味着把前九十九个的活儿重做一遍;有了它,你只做新词元那份活儿,其余的查表即可。这把生成从「平方级的功夫」变成「每词元近乎线性」,正因如此,交互式聊天机器人才能以可读的节奏流式吐字,而不是磨磨蹭蹭。缓存是实时生成之所以根本可行的最大单一原因。
但缓存不是免费的——它以计算换内存,而这笔内存账很陡。它的大小随层数、注意力头数与对话长度增长,所以一段长聊天可能仅为容纳缓存就吃掉数 GB 的快速内存,往往成了「一台服务器能扛多少用户」或「能撑多长上下文」的真正上限。近来许多工程——分组查询注意力、缓存压缩、分页内存——存在的意义,恰恰就是为了缩小这块占用。KV 缓存优美地说明了:在这门领域里,常常是内存、而非纯粹的算术,才是那条绑手绑脚的约束。
生成一段 500 词元的回复:到第 500 个词元时,注意力需要第 1 到第 499 个词元的键与值。没有缓存,模型每一步都把它们全部重算;有了缓存,它们各算过一次,如今只需读回,只为第 500 个词元做新的活儿。
键与值只算一次,往后每个词元都重复取用。
KV 缓存以计算换内存,而内存通常是更难的那道限。它的大小随层数、头数与对话长度增长,所以一段长聊天的缓存可能霸占一块 GPU 的内存,并卡住一台服务器能服务多少用户——这正是为何那么多服务端优化都直奔「缩小它」而去。
又称
另见