← 返回信息流
AI 资讯Hacker News·3 小时前

内存层映射技术减轻大模型过载

原标题:Mapping with In-Memory Layers to Reduce LLM Overload

速览

该方法通过内存层映射技术,在推理过程中动态管理模型层的加载与卸载,有效降低大语言模型的显存占用和计算负担。它能在不显著牺牲性能的前提下,支持更大规模或更多并发请求,提升系统效率。这一技术对推动LLM在资源受限环境下的部署具有实际意义。

AI 深度解读

背景

RidgeText 是一个构建在 LLM 之上的编排层,用户通过短信与之交互——无需应用、无需 UI。LLM 负责处理自然语言理解,决定调用哪些工具,并组合出清晰的回复发送给用户。它不是规则引擎,LLM 在每一步都要做出判断。

这种非确定性是对话的特性,但也给功能带来了约束:任何 LLM 接触的东西都需要能够容忍变化。如果某个工具返回的数据量过大,LLM 可能会截断、幻觉式摘要或静默失败;如果工具的接口不明确,LLM 可能会错误地调用它。好的工具设计意味着要塑造 LLM 所看到的内容,使其所有合理响应的范围都能导向正确的结果。

地图生成就是一个典型的例子,其中这一点尤为重要。

核心内容

朴素的方法(及其失败原因)

最直接的实现方式是:一个工具获取火灾数据并返回给 LLM,然后第二个工具接受这些数据并渲染地图。例如:

  • LLM 调用 get_wildfire_data() → 接收到 2000 个火灾多边形(GeoJSON 格式)
  • LLM 调用 render_map(geojson: ...) → 将 GeoJSON 传过去

在实践中,一个中等规模的野火数据集大约是 50–500KB 的原始 GeoJSON。每个 token 大约 4 字节,因此 500KB 大约是 125,000 个 token——比许多上下文窗口都要大,即便能容纳,成本也很高。LLM 变成了一个它无法对其数据进行推理的数据管道:它不能简化 GeoJSON,不能验证它,而且每次都要支付完整的上下文成本。

层优先模式(Layer-First Pattern)

RidgeText 的解决方案模仿了 Mapbox 本身的工作方式:图层被独立添加,在渲染时合成。不是把数据返回给 LLM,而是每个数据获取工具将结果存储在服务器端,只返回一个轻量级的确认信息:

  • LLM 调用 retrieve_wildfire_layer(location: "Cascades"){ status: "queued", layerId: "wildfires-0", featureCount: 847 }
  • LLM 调用 retrieve_trail_layer(trailName: "PCT Section J"){ status: "queued", layerId: "trail-1", featureCount: 1 }
  • LLM 调用 generate_map(){ mapUrl: "https://storage.../map-abc123.jpg" }

LLM 的上下文永远只看到这些确认信息——微小的 JSON 对象。GeoJSON 保存在服务器内存中,直到 generate_map 清空队列并合成图像。

图层栈

每个 retrieve_* 调用会追加一个有序的图层数组到请求上下文中。generate_map 按照插入顺序渲染它们——就像 Mapbox 的图层栈一样,较早的图层位于较晚的图层下方。LLM 通过调用工具的顺序隐式控制图层顺序:如果它先调用 retrieve_satellite_base 再调用 retrieve_trail,那么轨迹就会绘制在卫星影像之上。

实现使用一个按会话 ID 索引的进程内 Map,TTL 为 30 分钟,这样已排队但从未渲染的图层会被自动驱逐,而不会累积。具体机制不是重点——Redis、数据库或请求范围上下文对象都可以。关键在于数据存在于 LLM 上下文窗口之外的地方。

为什么这模仿了 Mapbox

Mapbox 的核心模型是:数据源(sources)提供数据,图层(layers)定义如何渲染,图层按声明顺序合成。RidgeText 的服务器端队列是同样的抽象,只是没有浏览器运行。

需要精确说明在渲染器中“Mapbox”的含义:它获取 Mapbox Static API 的图像作为基础瓦片(地形、道路、标注),然后使用 canvas 在之上合成数据图层。Mapbox 本身从不看到 GeoJSON;它只提供背景。存储的图层描述符遵循 Mapbox 的格式,不是因为渲染器需要它,而是作为一种有前瞻性的选择。

如果未来需要超越静态瓦片(如 3D 地形、复杂混合或动画图层),可以将渲染器替换为在 Playwright 浏览器中运行的无头 Mapbox GL JS 实例。这个渲染器会使用完全相同的图层队列,而无需更改工具或 LLM 的接口。成本和速度也会改变:基于 JavaScript 的渲染器可以跨请求缓存瓦片和 GL 资源,相比于每次为每个地图都调用全新的 Static API,可能降低每张地图的成本并改善冷启动延迟。

这意味着:

  • 添加新的数据源就是添加一个新的 retrieve_* 工具——渲染管线不变。
  • 图层顺序通过工具调用顺序自然表达。
  • 样式与图层类型放在一起,而不是通过 LLM 传递。
  • 渲染器是可替换的——今天用静态瓦片,明天用无头 GL——而不需要改动 LLM 层。

渲染步骤

generate_map 是确定性的。它从 LLM 那里不接收任何 GeoJSON——只接收可选参数,如缩放级别或地图样式。它读取图层队列,将每个要素集投影到 Mapbox Static API 基础图像上,并使用 sharp 进行合成。结果是一个单独的图像 URL,LLM 可以将其附加到短信回复中。

LLM 实际看到的

对于“显示 PCT 附近的野火”请求,LLM 的工具调用序列如下:

  • retrieve_wildfire_layer(location: "Cascades") → 约 50 字节
  • retrieve_trail_layer(trailName: "PCT Section J") → 约 50 字节
  • generate_map() → 约 100 字节

工具结果中的总 token 数:约 150。如果没有这种模式,则超过 125,000 个。

权衡

获得的优势:

  • 上下文窗口无论数据集多大都保持很小。
  • 渲染管线是确定性的,可以单独测试。
  • 添加新的图层类型不需要改变 LLM 与系统的交互方式。

付出的代价:

  • LLM 无法对它所排队的任何图层的底层几何进行推理。它知道添加了一条轨迹以及要素数量,但对坐标本身一无所知。像“离我轨迹最近的城市是哪个?”这样的问题无法从排队的图层数据中精确回答——LLM 需要一个单独的工具将该信息以文本形式返回。不过,LLM 稍后可以通过 Storage 链接查看渲染后的地图图像,并对合成结果进行视觉观察。
  • 图层队列是短暂的——它不会跨轮次持久化,因此多轮的地图精细化需要重新获取数据。

第二个代价可以通过将图层持久化到数据库表来解决,该表遵循与对话回复相同的历史保留策略。每个渲染的地图回复都会通过引用存储其关联的图层,这样如果用户后续跟进(要求放大、更改样式或添加另一个数据源),图层可以直接从数据库重新水化,而不需要从原始 API 重新获取。

将此模式应用于你的系统

这里的模式并非只关于地图。它关乎识别出你的 LLM 何时在充当数据管道而不是推理引擎——并将其从该角色中移除。需要留意的信号是:工具 A 获取数据 → LLM 接收 → LLM 直接传递给工具 B。如果 LLM 没有基于内容做出决策,就不应该持有内容。

几个适用同样方法的场景:

  • 多源数据增强:NREL 提供电动汽车充电站的数据集,但缺少其他 API 提供的便利设施数据、实时可用性和用户评价。与其分别获取每个数据源并把合并后的负载传回给 LLM 进行组合,不如让每个检索工具将其数据集排队到服务器端。一个合成器按站点 ID 将它们合并,并产生增强后的结果。LLM 编排哪些源需要拉取,并接收一个摘要——它从不持有中间的单源负载或合并后的数据集。

  • 多遍日志分析:用户问“过去一小时内我们有多少错误,主要问题是什么?”这需要两步……

(原文在此处中断,但模式类似:先获取数据,再分析,数据不经过 LLM 上下文。)

关键要点

  • 避免 LLM 成为数据管道:如果工具 A 获取数据、LLM 直接传给工具 B,且 LLM 未对数据做决策,就应该让数据绕过 LLM 上下文。
  • 层优先模式:数据获取工具将结果存储在服务器端(
查看原文 →ridgetext.com