上下文长度限制是所有 LLM 都存在的问题。以下存储库和相关论文表明,保留 4 个初始标记将使大多数常见 LLM 上的上下文长度无限大,而不会牺牲性能或效率。
代码:https://github.com/mit-han-lab/streaming-llm
存储库内的论文参考资料展示了 LLM 的注意力集中效应以及如何利用它。
当前行为上下文长度的限制主要由预训练定义。其他方法(如 rope 或滑动窗口)各有利弊,但没有一种方法可以达到比此方法更高的上下文长度。
上下文长度限制是所有 LLM 都存在的问题。以下存储库和相关论文表明,保留 4 个初始标记将使大多数常见 LLM 上的上下文长度无限大,而不会牺牲性能或效率。
代码:https://github.com/mit-han-lab/streaming-llm
存储库内的论文参考资料展示了 LLM 的注意力集中效应以及如何利用它。
当前行为上下文长度的限制主要由预训练定义。其他方法(如 rope 或滑动窗口)各有利弊,但没有一种方法可以达到比此方法更高的上下文长度。
是的,我已经读过这篇论文,好消息是,在 #3228 之后,这项技术在 中很容易得到支持llama.cpp
。从技术上讲,它已经通过n_keep == 4
在main
他们还展示了这项技术的内存效率(如果没有它,它会很早就运行 OOM)。这是否意味着无限上下文和稳定且低 VRAM 使用率?这将是革命性的,并使 vectorDB 过时。
他们还展示了这项技术的内存效率(如果没有它,它会很早就运行 OOM)。这是否意味着无限上下文和稳定且低 VRAM 使用率?这将是革命性的,并使 vectorDB 过时。
这不是你读到的无限上下文。它对注意力进行了新颖的修改,以便你可以生成“无限”输出
如果有人能确认我是否理解了该论文,我将不胜感激:
他们提出的是无限文本长度而不是无限上下文长度的解决方案,对吗?他们的观察是,“内部状态”的一致性在很大程度上取决于第一个标记,因此天真地保留初始标记并在其余标记上实现滑动上下文窗口,允许 LLM 保持其理智,并且第一个标记是“重要的”,因为从一侧附加标记,使第一个标记在 N 次迭代中“存在”,第二个标记在 N-1 次迭代中“存在”等,因此第一个标记在所有后续迭代中都被“看到”,但反之则不然?
他们还展示了这项技术的内存效率(如果没有它,它会很早就运行 OOM)。这是否意味着无限上下文和稳定且低 VRAM 使用率?这将是革命性的,并使 vectorDB 过时。
这不是你读到的无限上下文。它对注意力进行了新颖的修改,以便你可以生成“无限”输出
是的,我花了一段时间才明白,他们新发布的常见问题解答对此进行了澄清。我编辑了标题。我相信这是参与这个项目的一项好技术。
这是关于输入序列长度的问题,所以这次是上下文。看看那个稳定的内存使用情况!
关键点在于输入序列的长度可以非常长,但模型考虑的上下文保持不变。因此,您可以给它输入一本书,让它写出一本书的内容,但它不会“记住”或考虑 4,096 个标记之前的序列中的内容或其他内容。
VRAM 的使用率令人印象深刻。
我认为我们n_keep=4
还需要n_discard=1
在这里正确实现 StreamingLLM:https://github.com/ggerganov/llama.cpp/blob/master/examples/main/main.cpp#L504。
假设 llama.cpp 中 k-cache 的移位与论文中描述的行为相匹配,其中键是根据它们在缓存中的位置而不是文本进行旋转的(我相信它们是但不确定)
我认为我们需要 n_keep=4 以及 n_discard=1 才能正确实现 StreamingLLM:
没错,尽管我不认为真的需要转移每个新令牌。好处是微不足道的。
我认为这最大的影响是消除目前正在进行的昂贵的重新评估,但效果是一样的--n-keep 4
。
这是 RoPE 处理部分:modify_llama.py。我需要时间来理解它...
main
自从 #3228 合并以来,不再需要昂贵的重新评估server
。我们现在不是重新评估,而是“转移”KV 缓存,这是一个相对便宜的操作,在某种意义上相当于论文中提出的方法。我想说我们甚至有一个优势,因为我们可以选择设置,n_discard == 8
例如,这将使 RoPE 每 8 个 token 重新计算 1 次,而不是像在 StreamingLLM 中那样在每个 token 上重新计算 1 次
只是想知道,这是否为我们提供了选择滑动窗口开始位置的选项?例如,我有一个提示模板,如下所示:
<#meta#>
- Date: 2023-10-05
- Task: chat
<#system#>
You are a conversational AI having a turn based chat with a user.
<#chat#>
<#user#>
Message 1
<#bot#>
Response 1
<#user#>
Message 2
<#user_context#>
Some Context
<#bot#>
Response 2
<#user#>
Message 3
<#bot#>
Response 3
我可以锚定这部分吗:
<#meta#>
- Date: 2023-10-05
- Task: chat
<#system#>
You are a conversational AI having a turn based chat with a user.
<#chat#>
并且 kv 缓存仅在聊天部分转移?
或者我只是误解了某些事情?
是的 - 计算该部分中的令牌并设置n_keep
为等于该数字
n_keep 在推理期间可配置吗?我计划的功能之一是集成一个集成 LLM,它可以在推理期间的特定点修改提示模板。例如,更改当前任务,或更改系统提示以与响应中正在处理的当前问题保持一致,然后恢复推理。因此,该窗口中的标记数量可能会发生变化。
您可以修改它 - API 非常灵活。但要实现您的目标,需要做的不仅仅是更新n_keep
。一种方法是为每个提示设置单独的上下文,并在开始时对其进行评估。或者,您可以为不同的提示设置一个上下文和不同的序列 ID。