<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Serving on zzudongxiang</title><link>https://www.zzudongxiang.com/tags/serving/</link><description>Recent content in Serving on zzudongxiang</description><generator>Hugo</generator><language>zh-cn</language><copyright>2026 zzudongxiang.com · 豫ICP备2022012018号-1 · 豫公网安备41160202000614号</copyright><lastBuildDate>Wed, 28 Oct 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://www.zzudongxiang.com/tags/serving/index.xml" rel="self" type="application/rss+xml"/><item><title>记录一下部署vLLM过程中踩到的坑</title><link>https://www.zzudongxiang.com/posts/vllm-serving-kvpool/</link><pubDate>Wed, 28 Oct 2026 00:00:00 +0000</pubDate><guid>https://www.zzudongxiang.com/posts/vllm-serving-kvpool/</guid><description>&lt;h2 id="1-部署一个vllm服务"&gt;1. 部署一个vLLM服务&lt;/h2&gt;
&lt;p&gt;前一段手上拿到一批昇腾 910C，考虑到可以给大家部署一些vLLM服务来用，本来以为就是按照vLLM的官方教程一步一步走完就行了，事实上也确实是这样的，一步一步走完了流程，但是能用和好用确实是两回事情，后面为了vLLM好用踩了不少坑。&lt;/p&gt;
&lt;p&gt;先说一下我们用到的模型的情况，经过对kimi-k3、glm-5.2、glm-5.3-flash、deepseek-v4-flash、deepseek-vision等多个模型的测试，在推理性能、占用资源数、模型能力之间取了一个平衡，最终选择部署deepseek-v4.1-flash（dsv4.1-flash），上下文选择了一个比较适中的范围：600k，同时开启了dspark加速。&lt;/p&gt;
&lt;h2 id="2-多实例负载均衡"&gt;2. 多实例负载均衡&lt;/h2&gt;
&lt;p&gt;最先遇到的问题是单实例服务能力不够，最直接的想法就是搞多实例然后在new-api层做负载均衡，单手后期运维起来由于new-api没有做联动，有点运维难度，且负载均衡导致缓存命中降低，所以选择在vLLM和new-api之间加了一层router来做负载均衡。&lt;/p&gt;
&lt;p&gt;最早的router是配置文件形态：引擎列表写死在配置里，加减引擎要改配置、重载。引擎少的时候忍忍也就过去了。&lt;/p&gt;
&lt;p&gt;后来换了新一代动态router：引擎主动注册，自带cache-aware调度（前缀亲和，同一前缀尽量打到同一引擎）、失败重试、熔断摘除。和看门狗配合之后形成两层防御：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;看门狗&lt;/strong&gt;管&amp;quot;引擎挂死&amp;quot;：真实推理探针，连续失败整组重启；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Router&lt;/strong&gt; 管&amp;quot;坏引擎别接流量&amp;quot;：探活失败摘出路由，恢复后自动回归。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="部署形态演进" loading="lazy" src="https://www.zzudongxiang.com/posts/vllm-serving-kvpool/images/fig1-evolution.svg"&gt;&lt;/p&gt;
&lt;h2 id="3-kv缓存问题"&gt;3. KV缓存问题&lt;/h2&gt;
&lt;p&gt;影响vLLM的服务质量TTFT的最大因素就是KV缓存，由于我想部署多个实例，导致留给KV的空间就剩下很少了，所以就需要考虑把KV卸载到DRAM或者SSD上，最开始用到的就是MemCache来做KV缓存管理。共享缓存的第一步是 MemCache：vllm-ascend的AscendStoreConnector，在本机内存里开一块池，把前缀 KV 存出去，下一个请求来了先查池。&lt;/p&gt;
&lt;p&gt;但是在实际上线服务的时候遇到很多奇怪的问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;存的日志一切正常，块块都写进去了；&lt;/li&gt;
&lt;li&gt;审计计数器显示查询也在跑，exist请求源源不断，还能查到一部分key；&lt;/li&gt;
&lt;li&gt;但命中&lt;strong&gt;恒为 0&lt;/strong&gt;，TTFT 纹丝不动。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当时给它起了个名字叫&amp;quot;只存不取&amp;quot;，一度怀疑池子根本没接上。真正的转机是把日志开到DEBUG重启，再加一个受控探针：灌入约50k的前缀token → 用流量把池驱逐干净 → 原样重发。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;池侧逐组核对，exists全中：96/96、5/386……每个key都在；&lt;/li&gt;
&lt;li&gt;紧接着一行 &lt;code&gt;final hit=0&lt;/code&gt;；&lt;/li&gt;
&lt;li&gt;请求全量冷预填。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以不是&amp;quot;只存不取&amp;quot;，是&lt;strong&gt;查到了也算零命中&lt;/strong&gt;。卡点在&amp;quot;查到之后怎么算命中长度&amp;quot;。&lt;/p&gt;
&lt;p&gt;对着源码读才发现是粒度基不一致：池里存的是32-token粒度的块哈希，而vLLM core的契约写得明明白白——查命中时调用方必须传&amp;quot;对齐粒度 = 哈希粒度&amp;quot;（源码注释原话：&lt;em&gt;caller passes alignment_tokens = hash_block_size&lt;/em&gt;）。我们部署分支的协调器传的却是引擎块大小128。128对32，取出来的哈希和池里存的根本不是同一批值，第一块就miss，后面全部作废。&lt;/p&gt;
&lt;p&gt;先试了一行补丁：把128改成32，第一组立刻命中12288——成功了一组。但滑窗组不支持细粒度命中（直接断言），压缩器状态组的粒度又不一样，池侧还有一层按错误粒度截断的覆盖上限。修到最后确认：这个分支（vLLM 0.23）的命中路径就是个半成品，补丁救不完。&lt;/p&gt;
&lt;p&gt;真正的解法是上游 v0.30.0rc1 把这条路径正面重写了：查询集收窄到&amp;quot;可前缀缓存的组&amp;quot;，统一调度侧和 worker 侧的命中语义。换镜像，命中日志直接出现，一行补丁都没打。顺手还赚了个惊喜：新版本把查找表挪到了主机内存，腾出来的显存全给了KV池——&lt;strong&gt;池容量6.88倍&lt;/strong&gt;（98万 → 678万token），600K长文加16并发在容量上从此无障碍。&lt;/p&gt;
&lt;h2 id="4-共享kv池"&gt;4. 共享KV池&lt;/h2&gt;
&lt;p&gt;MemCache修好之后，后续的问题也逐渐暴露出来了：池是&amp;quot;每节点一份&amp;quot;的孤立池（元服务绑在本机回环地址上），跨节点从来没有真正通过；引擎一重启，池就空。用户的文档就那几份，却要每个引擎各存一份、重启全丢、再各预填一遍。&lt;/p&gt;
&lt;h3 id="41-memcache方案"&gt;4.1 MemCache方案&lt;/h3&gt;
&lt;p&gt;把各节点的元服务指到同一个中心点：段注册、挂载、全局rank偏移，所有前置步骤全绿。然后跨节点put，100%失败（error -1），重试的put风暴反手把引擎拖死。关掉fabric内存直传的开关复测，依旧。&lt;/p&gt;
&lt;h3 id="42-mooncake方案"&gt;4.2 Mooncake方案&lt;/h3&gt;
&lt;p&gt;换分布式KV store：master起来了、几十个段全部挂载成功、对端引擎也能连上——万事俱备。然后put计数恒为 0，设备侧内存拷贝全部超时（EE1002）。想退回普通TCP传输：vllm-ascend硬编码只认昇腾直连协议，NotImplementedError，此路不通。&lt;/p&gt;
&lt;h3 id="43-问题定位"&gt;4.3 问题定位&lt;/h3&gt;
&lt;p&gt;上述两个方案都是经过单实例验证过的，但是最后都卡死在KV传输上，可奇怪的是这批节点正常训练都NPU传输数据是完全没问题的，凭什么 KV 不行？&lt;/p&gt;</description></item></channel></rss>