鹤岗市网站建设_网站建设公司_表单提交_seo优化
2026/1/16 15:59:27 网站建设 项目流程

Character.ai 是一家领先的 AI 娱乐平台,全球用户约 2000 万。Character.ai 团队希望提升 GPU 性能,并降低推理成本。其应用需要在大规模场景下保持极低延迟。为实现这一目标,​Character.ai 找到了 DigitalOcean 和 ​AMD​。三方紧密合作,对 AMD Instinct™ MI300X 和 MI325X GPU 平台进行了深度优化,使生产环境的推理吞吐量​提升了 2 倍。

在优化配置的情况下,DigitalOcean 在保证出色的 p90 首 Token 响应速度与持续 Token 生成吞吐量的同时,实现了单节点更高的请求密度,整体性能超过了此前基于通用、未优化 GPU 基础设施的部署方案。

这些提升来自一系列平台级优化,包括:

面向大型 MoE 模型的并行化策略、 高效的 FP8 执行路径、 结合 AITER 的优化内核、 感知拓扑结构的 GPU 分配方式, 以及基于 DigitalOcean Kubernetes(DOKS)的生产级编排能力。

这些能力共同帮助 Character.ai 在不增加运维负担的前提下,实现了可预测的推理扩展。本文将深入介绍这些编排与调优策略。

本文是 DigitalOcean 架构师团队总结撰写的实践回顾,深度剖析本次与 ​AMD、Character.ai 团队协同优化业务性能与表现的经验。

技术深度解析概览

Character.ai 使用包括 Qwen、Mistral 在内的多种模型来支撑其应用。本文重点介绍我们如何在配备 AMD Instinct GPU 的 DigitalOcean GPU 集群上,对 Qwen3-235B Instruct FP8 模型进行优化。该工作负载此前运行在其他云厂商的通用、未优化环境中。迁移到 DigitalOcean 的 AMD Instinct™ MI325X 平台并完成相关优化后,在严格的延迟和并发约束下,请求吞吐量(QPS)最高提升了 2 倍。Character.ai 的业务负载要求极高,但通过与客户及 AMD 的深度协作,我们取得了超出其预期的成果,并最终促成了一份与 DigitalOcean 的多年期、年金额达数千万美元的 GPU 基础设施合作协议。

我们最初的目标,是在 AMD Instinct™ GPU 上运行 Qwen3-235B 模型,以优化 5600 / 140(ISL / OSL)的工作负载。核心目标是在每台 8 卡 MI325X 服务器上最大化 QPS,同时将 p90 首 token 延迟(TTFT)和单个输出 token 时间(TPOT)控制在既定上限内。完成全部优化后,相比其他云厂商的通用配置,我们在单台 8 卡 MI325X 服务器上实现了约 2 倍的 QPS 提升。

下面将详细介绍这些优化方案。在深入技术细节之前,先对后文中频繁使用的一些术语进行说明。

分布式服务(Distributed Serving)

该技术在单节点和多节点集群中部署多个副本,并将请求路由到各自独立的副本上。副本之间不共享权重或 KV 缓存。

在分布式推理系统中,路由通常基于多种启发式规则,例如负载情况、前缀缓存命中情况等。

在集群层面,Character.ai 还引入了“持久用户会话”的概念,用于保证同一用户的后续请求一致性,从而最大化 KV 缓存命中率。

张量并行(Tensor Parallelism,TP)

张量并行(Tensor Parallelism)会将模型的层或张量在多张 GPU 之间进行横向切分。所有 GPU 同时处理同一层,但各自只负责计算其中一部分输出。

这种方式适用于单张 GPU 显存无法容纳的大模型,但要求参与张量并行的 GPU 之间具备高速互连。因此,该技术主要面向数据中心级 GPU。

专家并行(Expert Parallelism,EP)

专家并行用于 MoE 模型。不同专家分布在多张 GPU 上,而不是在每张卡上复制。Token 会被路由到持有对应专家的 GPU。

由于采用稀疏激活,MoE 架构在内存使用上更高效。

AITER

AITER(AI Tensor Engine for ROCm)是 AMD 在 GitHub 上开源的高性能 AI 算子库,专为加速 AMD Instinct GPU 上的机器学习负载而设计。

它基于 Triton、Composable Kernel(CK)和汇编等技术,提供统一的平台,使开发者可以在 PyTorch、JAX 等框架中集成优化内核,从而最大化硬件效率。

技术优化

DP1 / TP8 / EP8 + AITER

Character.ai 使用 vLLM 来运行模型。这是他们首次在 AMD Instinct GPU 上部署,因此,确保其软件工具链可以平滑迁移至 AMD 平台至关重要。

AMD 已为 vLLM 上游贡献了大量 ROCm 支持,几乎实现了完整兼容,使基于 CUDA 的应用可以较为轻松地迁移到 ROCm,并支持主流开源模型。

在使用带 ROCm 支持的 vLLM 镜像运行 Qwen3 模型时,我们最初遇到了一些问题,例如模型加载阶段的内存访问错误,以及 TP、EP 与 AITER 之间的兼容性问题。

通过与各方的紧密技术协作,并向上游提交有针对性的修复,这些问题最终被解决,形成了一个稳定且高性能的 DP1 / TP8 / EP8 + AITER vLLM 配置。

适用于 DP1 / TP8 / EP8 + AITER 的 vLLM 配置示例

VLLM_USE_V1=1 SAFETENSORS_FAST_GPU=1 \ VLLM_ROCM_USE_AITER=1 VLLM_ROCM_USE_AITER_MOE=1 \ VLLM_USE_TRITON_FLASH_ATTN=0 \ vllm serve Qwen/Qwen3-235B-A22B-Instruct-2507-FP8 \ --tensor-parallel-size 8 \ --enable-expert-parallel \ --kv-cache-dtype fp8 \ --quantization fp8 \ --distributed-executor-backend mp \ --compilation-config '{"full_cuda_graph":false, "max_capture_size": 32768}' \ --trust-remote-code \ --disable-log-requests \ --enable-prefix-caching \ --max-model-len 32768 \ --max_num_batched_tokens 32768 \ --gpu-memory-utilization 0.90

上述配置有几个关键点需要注意。

–kv-cache-dtype 参数被明确设置为 fp8,即使模型本身已是 FP8 格式。这一点很重要,因为在 vLLM 中,KV 缓存和模型权重是分开管理的。所以,即使模型权重是 FP8,KV 缓存默认仍会采用模型内部精度(此处为 BF16)。显式地将 KV 缓存设为 FP8 有以下几点优势:可降低 VRAM 使用量(约减少 50%);由于内存带宽压力减小,吞吐量得到提升;并且能够增强系统处理更高并发用户的能力。

其次,MI325X 这类 AMD Instinct GPU 在硬件层面对 FP8 有很强的原生支持,峰值 FP8 算力为 2614.9 TFLOPs,开启稀疏性可达 5229.8 TFLOPs。

权重和 KV cache 都使用 FP8,可以让硬件始终走在“快速路径”上,避免在 BF16 与 FP8 之间频繁转换。

再来看 --quantization fp8 这个参数。虽然模型已经是 FP8,这个参数看起来有些多余,但其实并非如此。 vLLM 会将该参数作为“工厂配置”(参考经典面向对象语言中的工厂模式),用来决定在加载模型时实例化哪一种线性层实现。在 ROCm / AITER 环境下,这会触发 FP8Config,使 vLLM 使用专门的量化线性层,并调用 FP8 的 AITER MoE 内核。

Qwen3-235B 是一个包含 128 位专家的混合专家模型(可以通过模型 config.json 中的 num_experts 字段验证这一点)。使用 vLLM 时,启用专家并行模式(–enable-expert-parallel)非常重要,这样 vLLM 就不会将所有专家切分到全部 8 块 GPU 上,而是将完整的专家分布到各 GPU。使用 8 块 GPU 时,每块 GPU 将承载 128 / 8 = 16 个完整的专家。由于每块 GPU 持有完整的专家,MoE 路由层将特定的标记发送到持有对应专家的特定 GPU,从而大幅减少了需要在 GPU 之间移动的数据量。

我们还稍微调整了 CUDA 图编译设置({“full_cuda_graph”: false, “max_capture_size”: 32768})。在我们的模型性能和加载时间基准测试中,我们发现此设置是最优的。此外,当启用完整的 CUDA 图编译时,我们在 ROCm vLLM 上遇到了一些崩溃(很可能是 ROCm 堆栈与 CUDA 的某些互操作性问题)。对于分段编译(设置为 false),vLLM 将模型的执行分解成多个部分(注意力层之前和之后的部分)。它会为计算密集的线性层捕获 CUDA 图,但以即时执行模式运行注意力层。而完整编译则试图将整个前向传播过程(包括注意力层)捕获到一个巨大的 CUDA 图中,这可能影响:1) VRAM 利用率,2) 模型启动时间。CUDA 编译配置还包括一个 max_capture_size 设置,用于告诉 vLLM 要为之捕获图的最大序列长度。此设置与 --max-model-length 对齐,以确保 vLLM 为最长到 max_model_length 的序列捕获 CUDA 图,避免回退到可能影响性能的即时执行模式。

这里还有一些与上下文相关的参数也值得一提。我们将 --max-model-len 上限设置为 32768。该模型的默认原生上下文长度是 256K,如果我们保持默认值,vLLM 将尝试预留足够的 VRAM 来处理至少一个达到该最大长度的请求。对于我们试图优化的负载,我们知道不需要那么长。特定负载的平均输入序列长度 + 输出序列长度约为 6000,因此我们可以进一步降低此值以释放更多 VRAM。另外,–max_num_batched_tokens 也设置为 32768,与 --max_model_length 匹配。采用这种方法需要考虑一些细微之处:

  • 对于长提示将不会进行分块——这有利于优化首字元时间,因为 GPU 可以对整个提示运行完整的前向传播而无需分块,但代价是会出现巨大的计算峰值。
  • 对于长提示,VRAM 使用峰值会更高。这触及了 vLLM 调度器的核心,该调度器通过 v1 后端的分块预填充功能已得到显著改进。在设置 --max_num_batched_tokens 时总是需要权衡。将其设置得较高(32768)会带来更好的首字元时间、长提示下的更高吞吐量,但伴随着 VRAM 使用出现大幅峰值的风险;而设置得较低则会带来更好、更可预测的解码性能和更低的内存峰值。对于此负载,我们发现 32768 在 FP8 下是一个最佳平衡点。
  • 最后,我们启用了前缀缓存(–enable-prefix-caching)。这对于共享共同提示前缀的多轮对话特别有用,能让 vLLM 避免为已计算过的前缀重新计算 KV 缓存。这有助于降低延迟、提高生成吞吐量,同时减少计算峰值。

通过上述基于 DP1/TP8/EP8 的优化配置,并采用 AITER,我们最终实现的性能表现已优于 Character.ai 在其他云服平台上的部署方案。

DP2 / EP4 / TP4 + AITER

为了进一步提升 QPS,团队提出在单台 8 卡服务器上运行两个 TP4 组。

由于 Qwen-235B FP8 模型可以在 4 张 GPU 上容纳,并保留足够的激活和 KV cache 空间,因此推测 DP2 / TP4 / EP4 理论上可带来 2 倍吞吐量。

最终采用的配置如下。

VLLM_USE_V1=1 SAFETENSORS_FAST_GPU=1 VLLM_ROCM_USE_AITER=1 VLLM_ROCM_USE_AITER_MOE=1 VLLM_USE_TRITON_FLASH_ATTN=0 vllm serve Qwen/Qwen3-235B-A22B-Instruct-2507-FP8 \ --tensor-parallel-size 4 \ --enable-expert-parallel \ --kv-cache-dtype fp8 \ --quantization fp8 \ --distributed-executor-backend mp \ --compilation-config '{"full_cuda_graph":false, "max_capture_size": 32768}' \ --trust-remote-code \ --disable-log-requests \ --enable-prefix-caching \ --max-model-len 32768 \ --max_num_batched_tokens 32768 \ --gpu-memory-utilization 0.90

从 TP8 切换至 TP4 时,需要注意几个方面——

VRAM内存压力变化

从 TP8 配置转为 TP4 配置,意味着将原本分布在八张 GPU 上的模型权重合并到四张 GPU 上。在 TP8 模式下,每张 GPU 承载的权重内存约占 29GB;而在 TP4 模式下,这个需求会翻倍,达到每张 GPU 约 58GB。内存压力的增加,直接压缩了可用于 KV 缓存和激活内存的余量,从而限制了每张 GPU 所能支持的最大上下文长度和批处理大小。好在 MI325X 显卡具备 256GB 的 HBM 容量,因此这种 VRAM 的减少尚在可控范围内,并未构成显著的性能瓶颈。

专家并行度调整:从 EP8 到 EP4

将专家从八张 GPU 合并到四张 GPU 上,使得每张 GPU 上的专家数量增加至 32 个。更高的专家集中度也带来了硬件“热点”风险——因为特定的输入提示可能会同时将请求路由到位于同一张物理 GPU 上的多个专家。

硬件拓扑考量

ROCm/k8s-device-plugin(可以在 ROCm 的 github 中找到) 有一个基础的分配策略,用于根据 K8s 清单中 amd.com/gpu 参数的请求向 Pod 分配 GPU。当申请使用服务器中全部 8 张 GPU 时,硬件考量仍然重要——例如,强烈建议禁用 NUMA 平衡等。然而,当申请较小数量(例如 amd.com/gpu:4 用于 TP4)时,我们需要确保获得的是性能最优的 4 张 GPU 子集。

k8s-device-plugin 会执行一系列计算,为 TP4 配置提供最优设置。在设备初始化期间,它会准备一个评分矩阵:对位于同一 NUMA 节点并通过 xGMI 互联的 GPU 给予较低权重(即更优),而对通过 PCIe 连接或跨不同 NUMA 节点的 GPU 给予较高权重。权重最小的子集将胜出,并分配给 K8s Pod。

在 AMD MI325X 平台上,xGMI(Infinity Fabric)构成了一个全互联网状拓扑。每张 GPU 都与其他每张 GPU 有一条专用的 128 GB/s 双向链路。因此,从 GPU 间带宽的角度看,TP4 配置下任意 4 张 GPU 的组合(无论是否连续)都是同等最优的。

然而,如果系统是双路 CPU(这几乎是常态),则需要注意潜在的瓶颈:

  1. 跨NUMA​​节点选择GPU​:vLLM 进程需要管理分布在不同 CPU 插槽上的 GPU。每当 CPU 需要向另一个插槽上的 GPU 发送指令以启动计算内核时,该信号必须穿越 CPU-to-CPU 的 Infinity Fabric 链路。这可能导致首字元时间延长,并引起解码性能的波动。
  2. 跨插槽的 CPU 到GPU​​延迟​:对于不同 CPU 插槽上的 GPU,通过 PCIe 链路的 CPU 到 GPU 延迟相对较高。这可能影响“长”提示词序列向 GPU 的传输,从而拖慢首字元时间,并影响 TPOT 和 ITL 等解码指标。

下图展示了在单台 8 卡服务器上部署 DP2 / TP4 / EP4 配置的最优硬件/软件拓扑。

本质上,这是 N * (DP2 / TP4 / EP4) 的配置,其中 N 是集群中 8 卡 GPU 服务器的数量。在这些 N 台服务器集群的前端,有一层路由基础设施,能够最优地在各个模型 Pod 之间进行负载均衡。

通信与计算权衡

采用 TP4 后,每张 GPU 需要进行的通信跳数减少,但每张 GPU 需要承担的计算量却比 TP8 时增加了约 2 倍,这可能影响预填充和解码阶段的性能。

上图比较了 MI325X 上 DP1/TP8/EP8 与 DP1/TP4/EP4 的配置。正如预期,在首字元时间和每输出 Token 时间方面,单个 TP4 组没有任何一种情况优于 TP8。然而,如果对比大约 64 并发(这是目标工作负载)下的每秒查询数,我们可以计算出,两个 TP4 组(即 DP2/TP4/EP4 配置)提供的 QPS 大约是 DP1/TP8/EP8 的 2 倍。此外,在 64 并发下,我们仍然能够满足 p90 级别的首字元时间和每输出 Token 时间要求。

在相似的延迟和并发条件下,DP2/TP4/EP4 设置的吞吐量比 DP1/TP8/EP8 高出约 45%,相比其他提供商的通用设置则高出约 91%。这直接使得每个 Token 的成本按相似比例下降,从而显著降低了总体拥有成本。对于 Character.ai 而言,由于所需的吞吐量远超单台 8 卡服务器所能处理的范围,因此此配置在多个 8 卡 GPU 服务器上进行了水平扩展。

基础设施的配置

托管 Kubernetes

DigitalOcean Kubernetes(DOKS)是一款全托管的 Kubernetes 产品,可简化 Kubernetes 在 Day-0、Day-1 和 Day-2 阶段的运维工作。若自行管理,这些阶段往往非常复杂。DOKS 功能丰富,已被大量客户用于生产环境。近期还新增了对 1000 节点集群、原生 VPC 等重要能力。

在为 Character.ai 构建系统时,我们希望在 K8s 上运行 GPU 负载尽可能简单。GPU 驱动版本的安装与管理、K8s device plugin 的维护,都会显著抬高上手门槛,并带来长期运维负担。

DOKS 在集群创建完成后即可提供可用的 GPU 集群。K8s 工作节点基于 Debian 的虚拟化 GPU 实例(GPU Droplet),并预装了与硬件匹配的 GPU 驱动、K8s device plugin 以及 AMD 设备指标导出器,可实现开箱即用的体验。

这让 Character.ai 的接入流程非常顺畅。他们可以迅速启动 LLM 工作负载并投入使用。更重要的是,这些组件均由平台统一管理,用户无需操心维护或版本升级。

模型缓存优化

Character.ai 一直从 HuggingFace 下载 Qwen3 235B Instruct FP8 模型,该模型大小约 240GB。若每次启动新 Pod 都重新下载,会显著增加模型加载时间。DigitalOcean 近期推出的 NFS 产品在此场景发挥了重要作用:我们将模型权重缓存在 NFS 中,由 Pod 在启动时直接挂载读取,无需每次从互联网下载。这项优化使 vLLM 的模型加载时间缩短了 10-15%。

全新的 AI 系统范式

我们的分析总结了从实验环境迈向生产级 AI 基础设施所需的一系列关键转变,也强调了构建大规模推理最优架构的重要性,主要包括:

多维度优化推理性能需要在成本、延迟、吞吐量和并发能力之间取得平衡。合理的架构设计可以在提升整体性能的同时,显著降低单 token 成本。

基础设施范式转变在数据中心内部署大规模模型,与过去十多年传统 Web 服务的管理模式截然不同。这要求对部署策略进行全面的“全栈式”重构。

软硬件协同设计性能高度依赖底层系统架构,包括 CPU 到 GPU 的拓扑关系、GPU 之间的互联方式、内存带宽利用率以及 FLOPs 的发挥情况。只有让硬件约束、模型服务软件栈与具体的模型部署拓扑精确对齐,才能实现真正的峰值性能与效率。

精细化可观测性端到端的遥测数据至关重要,可用于发现潜在瓶颈、降低错误率,并挖掘成本与性能优化空间。

在持续打造 DigitalOcean 推理云的过程中,我们很高兴能与 AMD、Character.ai 等行业领军者携手合作。正如本文所展示的,借助 AMD Instinct GPU 以及 DigitalOcean 的可扩展平台与优化经验,可以在大规模场景下实现显著的性能提升。欢迎与我们的团队联系,了解如何获得类似的成果。


备注:文中提及的性能数据,包括请求​​吞吐量​(​​​QPS​*)提升 2 倍、相较未优化环境提升 91%,均基于 DigitalOcean 与 ​AMD​ 使用 Qwen3-235B Instruct FP8 模型进行的内部测试。测试条件包括 5600 / 140(ISL / OSL)的工作负载,以及 p90 首 token 延迟目标。实际性能可能会因模型选择、提示复杂度、硬件资源和网络状况而有较大差异。*

文中所说的“通用、未优化 ​GPU​ 基础设施”或“其他云厂商”,指的是未采用本文所述平台级优化方案的标准云实例,例如缺少基于 DOKS 的拓扑感知 GPU 分配、AITER 优化内核,以及定制的 DP2 / TP4 / EP4 ​并行策略。

文中提供的 vLLM 配置与环境变量仅供参考,代表针对 Character.ai 具体需求得出的最优实践。使用这些配置通常需要依赖 DOKS 提供的托管 ​GPU​ 驱动和 ROCm 支持。DigitalOcean 不保证在未经过专门验证的第三方软件或开源模型上获得完全一致的效果。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询