Skip to content

进阶主题

6.11.1 数学分析:以存换算的成本模型

Mooncake的"以存换算"理念可以通过数学模型严格证明其优势。设:

\(T_{recompute}\):重新计算KV Cache的时间

\(T_{transfer}\):传输KV Cache的时间

\(C_{compute}\):GPU计算成本($/小时)

\(C_{network}\):网络带宽成本($/GB)

\(S_{kv}\):KV Cache大小(GB)

\(B_{network}\):网络带宽(GB/s)

重计算成本: \(T_{recompute} = \frac{2 \times L \times d_{model}^2 \times seq_len}{GPU_FLOPS}\)

其中\(L\)是层数,\(d_{model}\)是模型维度,\(seq_len\)是序列长度。

传输成本: \(T_{transfer} = \frac{S_{kv}}{B_{network}} = \frac{2 \times L \times n_heads \times d_head \times seq_len \times \text{bytes\_per\_element}}{B_{network}}\)

成本平衡点: 当\(T_{transfer} < T_{recompute}\)时,传输比重计算更划算。在实际部署中,使用 RDMA ( 100-400Gbps )时:

  • 传输 128K token 的 KV Cache (约2GB)仅需0.04-0.16秒
  • 重新计算相同长度的KV Cache可能需要数秒

因此,在长上下文场景下,传输KV Cache的成本远低于重计算。

6.11.2 多级缓存替换策略

Mooncake Store实现了智能的多级缓存替换策略:

  1. LRU(Least Recently Used)
python
class LRUPolicy:
     def __init__(self, capacity):
        self.capacity = capacity
        self.cache = OrderedDict()

     def access(self, key):
        if key in self.cache:
             self.cache.move_to_end(key)
             return self.cache[key]
        return None


     def evict(self):
        return self.cache.popitem(last=False)[0] #last=False表示按照 FIFO顺序,即移除最早插入的那一项。

2. LFU (Least Frequently Used)

python
class LFUPolicy:
         def __init__(self, capacity):
            self.capacity = capacity
            self.key_freq = {}
            self.freq_keys = defaultdict(OrderedDict)
            self.min_freq = 0

         def access(self, key):
            if key not in self.key_freq:
                return None
            freq = self.key_freq[key]            # 当前频率
            del self.freq_keys[freq][key]        # 从原频率组中移除
            self.key_freq[key] = freq + 1        # 频率 +1
            self.freq_keys[freq + 1][key] = True # 加入新频率组
            if not self.freq_keys[self.min_freq]: # 如果原最小频率组空了
                self.min_freq += 1               # 最小频率上移
            return key

         def evict(self):
            key = next(iter(self.freq_keys[self.min_freq]))  # 取最小频率组的第一个 key
            del self.freq_keys[self.min_freq][key]           # 从频率组中删除
            del self.key_freq[key]                           # 从频率映射中删除
            return key
  1. 自适应混合策略
python
class AdaptiveCachePolicy:
      def __init__(self, capacity):
           self.capacity = capacity
           self.lru = LRUPolicy(capacity * 0.7)
           self.lfu = LFUPolicy(capacity * 0.3)
           self.hit_stats = {'lru': 0, 'lfu': 0}


      def access(self, key):
           #   尝试LRU
           result = self.lru.access(key)
           if result:
                  self.hit_stats['lru'] += 1
                  return result

           #   尝试LFU
           result = self.lfu.access(key)
           if result:
                  self.hit_stats['lfu'] += 1
                  return result

           return None


      def adapt_ratio(self):
           """ 根据命中率动态调整LRU/LFU比例"""
           total = sum(self.hit_stats.values())
           if total == 0:
                  return

           lru_ratio = self.hit_stats['lru'] / total
           lfu_ratio = self.hit_stats['lfu'] / total

           #   调整容量分配
           self.lru.capacity = int(self.capacity * lru_ratio)
           self.lfu.capacity = int(self.capacity * lfu_ratio)

6.11.3 网络拓扑感知路由

Transfer Engine 实现了网络拓扑感知路由,优化数据传输路径:

python
class TopologyAwareRouter:
     def __init__(self):
          self.topology = NetworkTopology()
          self.bandwidth_matrix = {}
          self.latency_matrix = {}
    
    
     def discover_topology(self):
          """ 发现网络拓扑结构"""
          nodes = self.get_all_nodes()
          for src in nodes:
                for dst in nodes:
                   if src != dst:
                       self.bandwidth_matrix[(src, dst)] = self.measure_bandwidth(src, dst)
                       self.latency_matrix[(src, dst)] = self.measure_latency(src, dst)


     def select_best_path(self, src, dst, size):
          """选择最优传输路径"""
          # 直接路径
          direct_bw = self.bandwidth_matrix.get((src, dst), 0)
          direct_latency = self.latency_matrix.get((src, dst), float('inf'))
          direct_time = size / direct_bw + direct_latency if direct_bw > 0 el

          #   通过中间节点转发
          best_relay_time = float('inf')
          best_relay = None

          for relay in self.get_all_nodes():
                if relay != src and relay != dst:
                   bw1 = self.bandwidth_matrix.get((src, relay), 0)
                   bw2 = self.bandwidth_matrix.get((relay, dst), 0)
                   lat1 = self.latency_matrix.get((src, relay), float('inf'))
                   lat2 = self.latency_matrix.get((relay, dst), float('inf'))

                   if bw1 > 0 and bw2 > 0:
                       relay_time = size / min(bw1, bw2) + lat1 + lat2
                       if relay_time < best_relay_time:
                           best_relay_time = relay_time
                           best_relay = relay

          #   选择最优路径
          if best_relay_time < direct_time:
                return ('relay', best_relay)
          return ('direct', None)

6.11.4 压缩与量化优化

为了减少KV Cache传输开销,Mooncake支持多种压缩技术:

KV Cache 量化

python
class KVCacheQuantizer:
        def __init__(self, bits=8):
            self.bits = bits
            self.scale = None
            self.zero_point = None

        def quantize(self, kv_cache: torch.Tensor):
            """  将FP16 KV Cache量化为INT8"""
            #   计算缩放因子和零点
            min_val = kv_cache.min()
            max_val = kv_cache.max()

            self.scale = (max_val - min_val) / (2 ** self.bits - 1)
            self.zero_point = -min_val / self.scale

            #   量化
            quantized = torch.round(kv_cache / self.scale + self.zero_point)
            quantized = torch.clamp(quantized, 0, 2 ** self.bits - 1)

            return quantized.to(torch.uint8)


        def dequantize(self, quantized: torch.Tensor):
            """ 反量化回FP16"""
            return (quantized.float() - self.zero_point) * self.scale

稀疏化传输

python
class SparseKVCacheTransfer:
     def __init__(self, sparsity_ratio=0.5):
          self.sparsity_ratio = sparsity_ratio

     def select_important_tokens(self, kv_cache, attention_scores):
          """选择重要的token进行传输"""
          # 基于attention scores选择重要token
          num_tokens = kv_cache.shape[2]
          num_keep = int(num_tokens * (1 - self.sparsity_ratio))

          #   计算每个token的重要性分数
          token_importance = attention_scores.sum(dim=(0, 1))

          #   选择最重要的token
          _, selected_indices = torch.topk(token_importance, num_keep)

          return kv_cache[:, :, selected_indices, :], selected_indices


     def reconstruct_full_cache(self, sparse_kv_cache, selected_indices, ful
          """ 重构完整的KV Cache"""
          full_cache = torch.zeros(
                sparse_kv_cache.shape[0],
                sparse_kv_cache.shape[1],
                full_length,
                sparse_kv_cache.shape[3],
                dtype=sparse_kv_cache.dtype,
                device=sparse_kv_cache.device
          )
          full_cache[:, :, selected_indices, :] = sparse_kv_cache
          return full_cache

6.11.5 安全性考虑

在生产环境部署Mooncake时,需要考虑以下安全因素:

数据传输加密

python
class SecureTransferEngine:
        def __init__(self, encryption_key):
            self.cipher = AES.new(encryption_key, AES.MODE_GCM)

        def encrypt_and_transfer(self, data, remote_session):
            """ 加密后传输数据"""
            encrypted_data, tag = self.cipher.encrypt_and_digest(data)
            return self.transfer_engine.transfer(
                  remote_session, encrypted_data, tag
            )

        def receive_and_decrypt(self, encrypted_data, tag):
            """ 接收并解密数据"""
            return self.cipher.decrypt_and_verify(encrypted_data, tag)

访问控制

python
class AccessControl:
        def __init__(self):
            self.allowed_nodes = set()
            self.token_blacklist = set()

        def authenticate_node(self, node_id, token):
            """ 验证节点身份"""
            if token in self.token_blacklist:
                  return False
            if node_id not in self.allowed_nodes:
                  return False
            return self.verify_token(token)

        def authorize_transfer(self, src_node, dst_node, data_size):
            """授权数据传输"""
            # 检查传输配额
            if not self.check_quota(src_node, data_size):
                  return False
            #   检查安全策略
            if not self.check_security_policy(src_node, dst_node):
                  return False
            return True

审计日志

python
class AuditLogger:
     def __init__(self, log_file):
           self.logger = logging.getLogger('mooncake_audit')
           handler = logging.FileHandler(log_file)
           self.logger.addHandler(handler)

     def log_transfer(self, src, dst, size, duration, status):
           """ 记录传输日志"""     
           self.logger.info(json.dumps({
                 'timestamp': time.time(),
                 'event': 'kv_transfer',
                 'src': src,
                 'dst': dst,
                 'size': size,
                 'duration': duration,
                 'status': status
           }))

     def log_access(self, node_id, action, resource, result):
           """  记录访问日志"""    
           self.logger.info(json.dumps({
                 'timestamp': time.time(),
                 'event': 'access',
                 'node_id': node_id,
                 'action': action,
                 'resource': resource,
                 'result': result
           }))

小结

Mooncake作为Kimi的底层推理平台,通过以KV Cache为中心的分离式架构,实现了大模型推理服务的重大突破。其核心创新包括:

  1. 以存换算理念:充分利用存储资源减少计算开销
  2. PD分离架构:独立优化Prefill和Decode阶段
  3. 分布式KV Cache池:跨节点共享和复用KV Cache
  4. 全局调度器:智能的请求路由和负载均衡
  5. 高性能传输引擎:RDMA/GDR零拷贝传输

Mooncake已在 Kimi生产环境中大规模部署,每天处理超过 1000亿 token,在 A800集群上多处理 115% 的请求,在 H800 集群上多处理 107% 的请求。其开源版本已与 vLLM 、SGLang等主流推理框架集成,成为AI推理基础设施领域的重要项目。

章明星教授领导的清华大学MADSys实验室与Moonshot AI的产学研合作,为Mooncake的成功奠定了坚实基础。该团队的研究成果发表在OSDI、SOSP、ASPLOS、FAST等顶级会议,Mooncake论文更是荣获FAST 2025最佳论文奖,标志着中国在AI基础设施领域的研究已达到国际领先水平。

随着AI Agent时代的到来,推理服务基础设施的重要性将进一步凸显。Mooncake及其背后的AI Serving Stack参考架构,将为下一代AI基础设施的发展提供重要参考。附录A:术语表

附录 A:术语表

术语英文说明
KV CacheKey-Value CacheTransformer模型中的键值缓存,用于加速自回归生成
PrefillPrefill Phase预填充阶段,并行处理输入token生成KV Cache
DecodeDecode Phase解码阶段,自回归生成输出token
PD分离Prefill-Decode Disaggregation将Prefill和Decode阶段分离到不同节点执行
TTFTTime To First Token首token时间,从请求到第一个输出token的延迟
TPOTTime Per Output Token每输出token时间,解码阶段的平均延迟
TBTTime Between Tokenstoken间时间,同TPOT
SLOService Level Objective服务等级目标,如延迟、吞吐量要求
RDMARemote Direct Memory Access远程直接内存访问,零拷贝网络技术
GDRGPUDirect RDMAGPU直接RDMA,GPU内存间的直接传输
MFUModel FLOPs Utilization模型FLOPs利用率,衡量GPU计算效率
MoEMixture of Experts混合专家模型,稀疏激活的大模型架构
EPExpert Parallelism专家并行,MoE模型的并行策略
TPTensor Parallelism张量并行,将模型层内切分到多GPU
PPPipeline Parallelism流水线并行,将模型层间切分到多节点
Prefix CachingPrefix Caching前缀缓存,复用共享前缀的KV Cache
GoodputGoodput有效吞吐量,满足SLO的成功请求数

附录B:参考资源

官方资源:

技术博客:

相关论文:

  • Efficient Large Language Models: A Survey
  • vLLM: Easy, Fast, and CheapLLM Serving with PagedAttention
  • Splitwise: Efficient Generative LLM Inference UsingPhase Splitting
  • DistServe: Disaggregating Prefill and Decoding for Goodput-optimizedLLM Serving

社区资源:

  • Mooncake Discord 社区
  • GitHub Discussions
  • Stack Overflow 标签 :mooncake, vllm, sglang

附录C:版本历史

版本日期更新内容
v0.1.02024-11-28Transfer Engine开源
v0.2.02024-12-16vLLM集成支持
v0.3.02025-03-07Mooncake Store开源
v0.4.02025-04-10SGLang集成支持
v0.5.02025-05-09NIXL后端支持
v0.6.02025-06-20LMDeploy后端支持
v0.7.02025-08-18昇腾NPU支持
v0.8.02025-12-23EPD分离支持
v1.0.02026-01-28PyTorch生态系统集成

附录D:性能调优指南

网络优化

python
#   启用巨页
echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages

#   调整RDMA参数
echo "options mlx4_ib enable_4k_uar=1" >> /etc/modprobe.d/mlx4.conf

#   优化网络中断绑定
./set_irq_affinity.sh mlx5_0

GPU 优化

python
#   设置GPU持久模式
 nvidia-smi -pm 1

 #   锁定GPU频率(可选)
 nvidia-smi -lgc 1410

 #   启用MIG(多实例GPU)
 nvidia-smi mig -cgi 19,19,19 -C

内存优化

python
#   增加文件描述符限制
 ulimit -n 65535

 #   调整内核参数
 echo 'vm.swappiness=10' >> /etc/sysctl.conf
 echo 'vm.dirty_ratio=40' >> /etc/sysctl.conf
 sysctl -p

Mooncake 特定优化

python
{
  "transfer_engine": {
    "batch_size": 32,
    "queue_depth": 128,
    "poll_mode": true
  },
  "cache": {
    "l1_size_gb": 40,
    "l2_size_gb": 200,
    "prefetch_enabled": true
  },
  "scheduler": {
    "prefill_decode_ratio": 0.5,
    "early_rejection_threshold": 0.9
  }
}

附录E:故障排查流程图

latex
 问题诊断流程

 ├─►  服务无法启动
 │       ├─► 检查etcd连接 ──► 检查网络连通性
 │       ├─► 检查RDMA设备 ──► 运行ibstat
 │       └─► 检查端口占用 ──► netstat -tlnp

 ├─►  传输性能差
 │       ├─► 测试RDMA带宽 ──► ib_read_bw
 │       ├─► 检查PCIe配置 ──► lspci -vv
 │       └─► 检查CPU频率 ──► cpupower frequency-info

 ├─► KV Cache命中率低
 │       ├─► 检查缓存大小 ──► 增加l1/l2缓存
 │       ├─► 分析请求模式 ──► 调整缓存策略
 │       └─► 检查Prefix长度 ──► 优化prefix匹配

 └─► 内存不足
         ├─► 检查内存泄漏 ──► valgrind/vmtools
         ├─► 调整内存池大小 ──► 修改配置
         └─► 启用SSD缓存 ──► 配置l3缓存

关于本章节

本章节由AI助手根据Mooncake官方文档、FAST 2025论文、GitHub仓库以及公开技术博客综合编写而成。内容力求准确全面,但由于技术快速发展,部分细节可能随版本更新而变化。建议读者参考官方文档获取最新信息。

致谢

感谢Moonshot AI和清华大学MADSys实验室开源Mooncake项目,为大模型推理基础设施的发展做出重要贡献。感谢所有开源社区贡献者的辛勤工作。

补充说明:Mooncake与AI Serving Stack的关系

AI Serving Stack是章明星团队提出的新一代AI推理服务参考架构,Mooncake是其中的核心组件之一。AI Serving Stack的整体架构包括:

  1. 接入层(Ingress Layer) - 负载均衡和流量管理 - 请求路由和分发 - 安全防护和限流
  2. 调度层( Scheduling Layer ) - Mooncake Conductor 全局调度器 - 弹性伸缩控制器 -资源配额管理
  3. 计算层( Compute Layer) - vLLM/SGLang等推理引擎 - Prefill/Decode分离部署 - 异构硬件支持
  4. 存储层(Storage Layer) - Mooncake Store分布式KV Cache池 - 多级缓存管理 - 持久化存储
  5. 传输层( Transport Layer) - Mooncake Transfer Engine - RDMA/GPUDirect支持 - 拓扑感知路由

AI Serving Stack 的设计目标是提供一个完整的、可组合的、开源的 AI 推理服务解决方案,支持从边缘设备到超大规模数据中心的各种部署场景。章明星团队与阿里云、蚂蚁集团、趋境科技等机构合作,持续推动AI Serving Stack的演进和生态建设。

目前,AI Serving Stack已获得InfoQ"2025年度AI工程与部署卓越奖",并在多家企业的生产环境中得到验证。对于即将加入Mooncake团队的实习生来说,理解AI Serving Stack的整体架构将有助于更好地把握Mooncake在更大生态系统中的定位和作用。

用心记录,持续成长