今天重温下自研推理工程的设计架构, 也便于我们深刻理解推理工程中的可能的优化点。
整体如图
1. vllm
vLLM 代表虚拟大语言模型,vLLM包括一个推理服务器和一个推理引擎(加速推理), 通过PagedAttention算法加速GPU显存的使用 来提高吞吐量。
为理解请求,LLM 需要了解字词之间的关系以及如何在字词之间建立关联,LLM 是通过数学运算来“推理”的, 面对大量用户请求时, 需要消耗大量显存。
从本质上讲,vLLM 作为一组指令,通过持续对用户响应进行“批处理”,促使 KV 缓存创建快捷方式。
① KV Cache: 是一种短期内存存储, 它是将每个token(词元)所对应的KV保存到缓存中, 以空间换时间的方式支持快速推理。
② 连续批处理:是一种可同时处理多个查询的技术(将先前计算的查询词元创建快捷方式),。
借助vLLM,LLM可以将批处理请求中重复部分的词元(“what is the capital of”)保存在短期记忆(KV 缓存)中,并发送一个“翻译请求”,而不是两个单独的请求。
2. vllm prooduction stack
- 快速扩缩容
- 可观测性
- 通过请求路由 和KV Cache 卸载来提升推理性能
LLMCache/Router:
可用的路由策略:"roundrobin" # @schema enum:[roundrobin,session,prefixaware,kvaware,disaggregated_prefill,disaggregated_prefill_orchestrated]
前缀感知路由可确保后续具有相同提示前缀的请求被路由到同一实例,从而最大限度地提高键值缓存的利用率并提升性能。
以下针对对话模型开启 前缀感知路由,默认使用k8s服务发现(推理服务Pod上均有 app.kubernetes.io/component=serving-engine 标签)。
<span>servingEngineSpec:</span>
<span>enableEngine:</span> <span>false</span>
<span>cacheserverSpec:</span>
<span>enabled:</span> <span>false</span>
<span>routerSpec:</span>
<span>enableRouter:</span> <span>true</span>
<span>routingLogic:</span> <span>"prefixaware"</span> <span># 按照请求prompt的前缀来路由,把相同前缀的请求都路由调度到同一后端</span>
<span>replicaCount:</span> <span>2</span>
<span>serviceMonitor:</span>
<span>enabled:</span> <span>true</span>
<span>startupProbe:</span>
<span>initialDelaySeconds:</span> <span>5</span>
<span>periodSeconds:</span> <span>10</span>
<span>failureThreshold:</span> <span>60</span>
<span>imagePullPolicy:</span> <span>"IfNotPresent"</span>
<span>env:</span>
<span>-</span> <span>name:</span> <span>TZ</span>
<span>value:</span> <span>"Asia/Shanghai"</span>
<span>extraArgs:</span>
<span>-</span> <span>"--k8s-label-selector"</span>
<span>-</span> <span>"app.kubernetes.io/component=serving-engine"</span> <span># 服务发现,推理服务的Pod上都有这个标签</span>
<span>resources:</span>
<span>limits:</span>
<span>memory:</span> <span>4Gi</span>
<span>requests:</span>
<span>cpu:</span> <span>400m</span>
<span>memory:</span> <span>2Gi</span>
这里面有一个问题,非对话模型是不能使用prefixaware, kvaware 路由策略:
向量模型Qwen/Qwen3-Embedding-8B发出的请求如下, 而对话模型会有prompt字段。
curl -X POST https:<span>//tokengine.hanyoai.com/v1/embeddings \</span>
-H <span>'Authorization</span>: Bearer sk-YJ3fOnCRGMHH2gzLeShdeduYXuJUF4TG5qrSmihvTIl2bBhK' \
-H <span>'Content</span>-Type: application/json' \
-d '{<span>"model"</span>:<span>"Qwen/Qwen3-Embedding-8B"</span>,<span>"input"</span>:<span>"待向量化文本"</span>}'
<span>// Internal Server Error</span>
我们的方案是在上层提前分流:
- 新建一个走roundrobin 路由
- 在上层higress上将这些非对话模型的请求路由到 这个roundrobin 路由。
整体的对外输出, 还是可以保持 higress gateway 不变。
该方案以最小改动解决混合模型路由难题:对话模型享前缀缓存,向量模型走轮询,网关统一对外。适用于同时自部署对话与向量模型的推理平台。