ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

TensorZero 实战:使用 Modal + vLLM 一键云端部署 OpenAI gpt-oss 开源推理模型

2026/9/15 13:23:32 拓冰建站 浏览量
TensorZero 实战:使用 Modal + vLLM 一键云端部署 OpenAI gpt-oss 开源推理模型 TensorZero 实战使用 Modal vLLM 一键云端部署 OpenAI gpt-oss 开源推理模型【免费下载链接】tensorzeroTensorZero is an open-source LLMOps platform that unifies an LLM gateway, observability, evaluation, optimization, and experimentation.项目地址: https://gitcode.com/GitHub_Trending/te/tensorzero本篇技术指南围绕 TensorZero 仓库中的 vLLM Modal 部署 gpt-oss 示例 展开讲解如何把 OpenAI 开源的 gpt-oss-20B / 120B 推理模型以单张 H100 GPU 的规模部署为 HTTP 推理服务。你将掌握gpt-oss 的核心技术特性MXFP4 量化、Attention Sinks、Harmony 响应格式、基于 Modal 的自定义容器镜像构建、模型权重与 vLLM 编译产物的卷缓存策略以及vllm serve关键启动参数CUDA Graph 捕获、Tensor Parallel、FAST_BOOT 权衡的配置方法。该示例是 TensorZero 在 E2E 测试环境中为推理模型提供持久、安全 HTTP 端点的一类部署方案与仓库中 SGLang 部署示例 等并列存在。部署入口一条命令完成全部编排仓库中该示例的入口文档 README.md 仅一行命令uv run modal deploy vllm_gpt_oss.py但这条命令背后是一份高度文档化的完整部署脚本152 行它囊括了从模型选择、容器镜像定制、权重缓存到 vLLM 引擎启动参数的完整链路。uv run通过项目内的 pyproject.toml 一类的依赖声明解析 Modal Python SDKmodal deploy则将脚本中定义的 Modal App此处名为vllm-gpt-oss-20b及其关联的镜像、卷、GPU 函数发布为常驻云端服务。说明该脚本头部带有pytest: false标记表明它不会被 pytest 当作测试收集而是作为部署 fixture 使用——这与仓库中 vllm-inference-qwen-modal、sgl-modal 等部署示例的模式一致它们的 README 也均只保留一行modal deploy命令。gpt-oss 模型背景为什么要关注这三个特性脚本注释首先交代了部署对象的技术背景。gpt-oss 是 OpenAI 开源的推理reasoning模型提供gpt-oss-120B与gpt-oss-20B两种规模两者均为**混合专家Mixture of Experts, MoE**架构总参数量大但单次推理实际激活的参数量少从而在保留世界知识与能力的同时获得更快的推理速度。部署该模型需要理解以下三个关键特性MXFP4MoE 层的 4-bit 块量化gpt-oss 在 MoE 层使用了一种较少见的 4-bitmxfp4浮点格式MX 格式家族源于arXiv:2310.10537。这是一种块量化格式将e2m1浮点数与按块的缩放因子blockwise scaling factors结合在压缩权重大小的同时尽量保留精度注意 attention 运算不做量化。因此部署镜像必须使用支持 MXFP4 的 vLLM 特供版本见下文vllm0.10.1gptoss。Attention Sinks长上下文的注意力水槽Attention sink 机制允许模型在不牺牲输出质量的前提下支持更长上下文。vLLM 团队为此提前为Flash Attention 3FA3加入了 attention sink 支持。这意味着要发挥 gpt-oss 的长上下文能力依赖链上需要配套的 vLLM 预发布版本与夜间版 PyTorch用于 Triton 支持这正是镜像定制环节的由来。Harmony 响应格式多通道输出gpt-oss 使用 OpenAI 的harmony 响应格式训练使模型能够通过多个通道输出思维链chain-of-thought, CoT通道、工具调用前导input tool-calling preamble通道以及常规文本响应通道。示例脚本为简洁起见采用更简单的格式未显式启用 harmony 多通道但如果你需要完整的 CoT 与工具调用能力可以参考 OpenAI 官方 cookbook 中关于 harmony 格式的说明。构建自定义容器镜像特供 vLLM 夜间 PyTorch脚本用 Modal 的ImageAPI 定义了一个自定义运行环境这是整套部署的基础import modal vllm_image ( modal.Image.from_registry( nvidia/cuda:12.8.1-devel-ubuntu22.04, add_python3.12, ) .entrypoint([]) .uv_pip_install( vllm0.10.1gptoss, huggingface_hub[hf_transfer]0.34, preTrue, extra_options--extra-index-url https://wheels.vllm.ai/gpt-oss/ --extra-index-url https://download.pytorch.org/whl/nightly/cu128 --index-strategy unsafe-best-match, ) )几个要点逐条拆解基础镜像nvidia/cuda:12.8.1-devel-ubuntu22.04是 CUDA 12.8 的开发版镜像包含编译/运行 vLLM 内核所需的头文件与工具链add_python3.12让 Modal 在镜像上安装 Python 3.12 运行时。.entrypoint([])清空基础镜像自带的入口命令避免与后续启动流程冲突。依赖安装核心是vllm0.10.1gptoss这个特供预发布版本它专门为 gpt-oss 的 MXFP4 与 attention sink 需求而构建huggingface_hub[hf_transfer]0.34启用 HF 的高速传输后端以加速权重下载。preTrue声明安装的是预发布版本。extra_options追加 pip 源配置——--extra-index-url https://wheels.vllm.ai/gpt-oss/指向 gpt-oss 专用 wheel 仓库https://download.pytorch.org/whl/nightly/cu128指向 CUDA 12.8 的 PyTorch 夜间构建提供 Triton 支持--index-strategy unsafe-best-match允许 pip 在多个源之间按版本匹配选择。这段配置说明了一个重要事实gpt-oss 的部署不是拿通用 vLLM 即可完成必须使用配套版本否则 MXFP4 权重无法被正确加载。模型选择与权重缓存Volumes 避免重复下载模型与版本固定脚本默认下载 Hugging Face 上的 20B 模型并固定 revision以保证可复现性MODEL_NAME openai/gpt-oss-20b MODEL_REVISION f47b95650b3ce7836072fb6457b362a795993484若显存充裕可切换到openai/gpt-oss-120bH100/H200 单卡即可容纳同时把 revision 换成对应的提交哈希。两级缓存卷vLLM 虽然支持按需从 Hugging Face 拉取权重但如果每次容器冷启动都重新下载既慢又费流量。脚本用两个Modal Volume共享磁盘做持久化缓存hf_cache_vol modal.Volume.from_name(huggingface-cache, create_if_missingTrue) vllm_cache_vol modal.Volume.from_name(vllm-cache, create_if_missingTrue)huggingface-cache挂载到/root/.cache/huggingface缓存模型权重vllm-cache挂载到/root/.cache/vllm缓存 vLLM 在首次运行时生成的编译产物。为什么要缓存后者vLLM 引擎启动时会做若干编译工作含 CUDA Graph 捕获这些产物在全新机器上首次生成耗时很长持久化后后续扩容或缩容到零再拉起时即可直接复用显著缩短冷启动时间。启动性能权衡FAST_BOOT 与 CUDA GraphvLLM 的编译配置直接影响启动延迟 vs 推理性能这对矛盾。脚本抽象出一个高层开关FAST_BOOT False # slower boots but faster inference并据此推导 CUDA Graph 捕获尺寸列表MAX_INPUTS 32 # how many requests can one replica handle? tune carefully! CUDA_GRAPH_CAPTURE_SIZES [ # 1, 2, 4, ... MAX_INPUTS 1 i for i in range((MAX_INPUTS).bit_length()) ]CUDA Graph把多次内核启动录制为一张图运行时一次性回放从而大幅降低 CPU 调度开销。MAX_INPUTS单个副本replica能同时处理的请求数直接决定并发上限脚本注释特别提醒谨慎调节。列表按 2 的幂展开1、2、4、…、32即针对不同批次规模预生成捕获图避免未来出现新尺寸时再触发 JIT 捕获的额外延迟。FAST_BOOT决定引擎以哪种模式启动FAST_BOOT True追加--enforce-eager同时禁用 Torch 编译与 CUDA Graph 捕获启动最快、吞吐最弱适合快速验证FAST_BOOT False追加--no-enforce-eager与-O.cudagraph_capture_sizes[1, 2, 4, 8, 16, 32]保留编译与图捕获推理性能最佳。定义并启动 vLLM 服务Modal App 的完整配置最终的服务函数把以上所有要素组装起来app modal.App(vllm-gpt-oss-20b) N_GPU 1 MINUTES 60 # seconds VLLM_PORT 8000 app.function( imagevllm_image, gpufH100:{N_GPU}, scaledown_window5 * MINUTES, # how long should we stay up with no requests? timeout5 * MINUTES, # how long should we wait for container start? volumes{ /root/.cache/huggingface: hf_cache_vol, /root/.cache/vllm: vllm_cache_vol, }, ) modal.concurrent(max_inputsMAX_INPUTS) modal.web_server(portVLLM_PORT, startup_timeout5 * MINUTES, requires_proxy_authTrue) def serve(): import subprocess cmd [ vllm, serve, --uvicorn-log-levelinfo, MODEL_NAME, --revision, MODEL_REVISION, --served-model-name, MODEL_NAME, llm, --host, 0.0.0.0, --port, str(VLLM_PORT), ] # enforce-eager disables both Torch compilation and CUDA graph capture # default is no-enforce-eager. see the --compilation-config flag for tighter control cmd [--enforce-eager if FAST_BOOT else --no-enforce-eager] if not FAST_BOOT: # CUDA graph capture is only used with --enforce-eager cmd [-O.cudagraph_capture_sizes str(CUDA_GRAPH_CAPTURE_SIZES).replace( , )] # assume multiple GPUs are for splitting up large matrix multiplications cmd [--tensor-parallel-size, str(N_GPU)] print(cmd) subprocess.Popen( .join(cmd), shellTrue)各装饰器与参数的含义配置项值作用gpuH100:1使用 1 张 H100120B 也可用 H200 单卡脚本注释说明多卡按切分大矩阵乘法的 Tensor Parallel 思路使用scaledown_window5 分钟无请求时保持存活的时间之后 Modal 自动缩容到零以节省成本timeout5 分钟等待容器启动的最长时间含镜像拉取、vLLM 编译volumesHF 缓存 vLLM 缓存挂载前述两个缓存卷modal.concurrentmax_inputs32单个副本最多并发处理 32 个请求与 CUDA Graph 捕获尺寸上限保持一致modal.web_server端口 8000requires_proxy_authTrue暴露为 HTTP Web 服务并要求代理认证——即外部访问需携带有效凭据这也是 TensorZero 用它充当安全测试后端的关键vllm serve的启动参数同样值得留意--revision锁定 Hugging Face 权重提交哈希保证行为可复现--served-model-name对外暴露的模型名TensorZero 等客户端用这个名字请求--host 0.0.0.0 --port 8000监听所有网卡、固定端口--tensor-parallel-size 1单卡场景下值为 1若改为多卡vLLM 会把大矩阵乘法切分到多张 GPU 上-O.cudagraph_capture_sizes以紧凑形式无空格传入捕获尺寸列表。脚本末尾用subprocess.Popen(..., shellTrue)把拼接好的命令行异步拉起vLLM 随即在 8000 端口提供兼容 OpenAI 的推理 API。启动日志--uvicorn-log-levelinfo会打印实际执行的完整命令便于排查问题。从部署到接入在 TensorZero 中消费该端点该部署示例在仓库中的定位是为推理模型提供持久、安全需 Bearer 认证、OpenAI 兼容的 HTTP 端点供 E2E 测试等场景使用。同类模式还出现在 SGLang 部署示例 以及基于 NGINX 做 Bearer Token 认证的 sgl-nginx 与 tgi-nginx 镜像中——后两者通过docker run以环境变量BEARER_TOKEN注入密钥、并把模型路径/ID 作为命令行参数传入思路与 Modal 方案互补。部署完成后该端点即成为符合 OpenAI 协议的服务可按 TensorZero 配置文档的方式把base_url指向 Modal 生成的 Web Server 地址并配置对应认证信息从而让 gpt-oss 以自托管模型的身份参与推理、评估与优化链路。小结与排障建议版本绑定gpt-oss 必须配合vllm0.10.1gptoss与 CUDA 12.8 夜间 PyTorch混用通用 vLLM 会导致 MXFP4 权重加载失败冷启动 vs 性能首次部署建议FAST_BOOT False以获得最佳吞吐若只是验证链路可临时设True加速启动缓存复用保持huggingface-cache、vllm-cache两个卷存在并挂载可显著缩短后续扩缩容时的启动时间并发与捕获尺寸调整MAX_INPUTS时CUDA Graph 捕获列表会自动按 2 的幂扩展二者需与modal.concurrent(max_inputs...)保持一致安全访问requires_proxy_authTrue意味着访问需经 Modal 代理认证接入 TensorZero 时需在客户端侧配置相应凭据。通过这份示例你可以把 OpenAI 的 20B/120B 开源推理模型以接近零运维的方式部署为可复现、可弹性伸缩的推理服务并作为 TensorZero 的自托管模型后端投入生产。【免费下载链接】tensorzeroTensorZero is an open-source LLMOps platform that unifies an LLM gateway, observability, evaluation, optimization, and experimentation.项目地址: https://gitcode.com/GitHub_Trending/te/tensorzero创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考