每次搜索的第一步:Perplexity 如何把嵌入模型的推理开销压到极限 ? Perplexity 的每一个答案,都始于嵌入与排序模型从 EB 级索引中挑出最相关的结果。 Perplexity 拆...

meng shao(@shao__meng) · 人工智能

每次搜索的第一步:Perplexity 如何把嵌入模型的推理开销压到极限 ? Perplexity 的每一个答案,都始于嵌入与排序模型从 EB 级索引中挑出最相关的结果。 Perplexity 拆解了它背后的服务基础设施:当 GPU 计算已趋于最优,加速空间在 GPU 之外,CPU 调度、kernel 启动开销、主机-设备同步、请求路由。团队通过三层架构(Ivy / Tulip / ROSE)加两项关键技术(整模型 CUDA Graph + LazyTensor 异步追踪)来吃掉这些开销,在延迟和吞吐上优于 vLLM v0.22.0。 perplexity.ai/hub/blog/fast-… # 问题定义:嵌入推理的两种流量形态 Perplexity 做了一个很关键的类比,把嵌入推理映射到 LLM 推理的已知模式上: · 批量嵌入(建索引/重索引):大批量长文档,追求最大吞吐以降低成本。计算特征等同于 LLM 的 Prefill 阶段,属于算力受限(compute-bound)。 · 重排打分(向量检索之后):中等批量,需要在吞吐与延迟之间取得平衡。同样对应 Prefill,瓶颈介于算力与带宽之间。 · 在线嵌入(用户查询):只有几个 token,追求最低延迟。计算特征等同于 LLM 的 Decode 阶段,属于显存带宽受限(memory-bound)。 这个映射的工程意义在于:他们不需要为嵌入模型单独写一套 kernel。LLM 服务栈里已经调优过的 prefill 和 decode kernel 可以直接复用,pplx-embed 和 Qwen3.5 的 LLM decoding 走的是同一套 kernel。 # 三层架构:Ivy → Tulip → ROSE Ivy(Rust HTTP 网关) 负责所有 CPU 侧预处理:JSON 解析、分词、输入模板、批次切分,再转成自定义 gRPC 协议发给下游。把这些从推理实例剥离出来的好处是,分词和格式化参数可以独立调整,不用碰昂贵的 GPU 实例。Ivy 还承担负载均衡:把大批量请求切块分发到多个副本,避免单个副本被大请求压垮。另外他们自研的 unigram 分词器已全量上线,对延迟改善显著(这是另一篇博文的内容)。 Tulip(Rust gRPC 推理服务器) 基于 tokio + tonic,做调度和批处理。调度策略刻意做得极简:先来先服务,请求在 GPU 忙时自然累积,空闲时打包发出。 这个"简单"是有理论依据的。他们观察到:对小型嵌入模型、在实际服务的序列长度下,dense 层的线性开销主导,attention 的二次开销可以忽略。所以延迟基本与 token 总数成正比,与序列数无关。一旦批次达到约 512 token(十亿参数以下的模型),GPU 就已饱和,再塞更多序列没有收益。既然如此,复杂的调度算法带来的边际价值就很小。 ROSE(Runtime-Optimized Serving Engine,Python) 真正的模型实现层,定义 kernel、层、模型结构、前向传播和 CUDA Graph 管理。它原本为 LLM 服务而建,通过一个 step() 函数与 Tulip 桥接——接收一个 batch,返回一个指向 GPU 上计算结果的引用(而非结果本身,这点后面很关键)。 嵌入模型与 LLM 的差异被限定在 attention 层:嵌入不需要 KV cache,改用支持 ragged(变长非填充)输入的 attention kernel 变体,避免 padding 浪费。dense 层则完全一致,因为 token 向量本来就是独立处理的。 # 核心技术一:整模型 CUDA Graph + 惰性捕获 为什么需要? 一次前向传播是 CPU 与 GPU 的交替配合:CPU 负责调度和 kernel 启动,GPU 负责矩阵乘法、attention、norm、激活。大批量时 GPU 执行时间长,CPU 开销可忽略;但小批量时,Python/PyTorch 的 kernel 启动开销会反过来超过 GPU 实际计算时间。嵌入模型本身很小,这个"拐点"来得很早——文中说在数千 token、几十个序列的批次规模上 CPU 开销才被 GPU 时间盖过。也就是说,在线查询这种几十 token 的请求,绝大部分时间在等 CPU。 做法 CUDA Graph 把整个前向传播的所有 kernel 启动元数据一次性捕获,之后一次驱动调用即可回放,跳过所有 Python 代码。Perplexity 为所有嵌入模型构建整模型级别的图。有些 attention 实现依赖主机侧动态输入来配置 kernel 启动,会破坏图捕获,他们把修复上游到了相关 kernel 库。 代价与缓解 CUDA Gra

查看原文