跳到内容

GPT OSS

gpt-oss vLLM 使用指南

gpt-oss-20bgpt-oss-120b 是 OpenAI 开源的强大推理模型。在 vLLM 中,您可以在 NVIDIA H100、H200、B200 以及 MI300x、MI325x、MI355x 和 Radeon AI PRO R9700 上运行它。我们正在积极确保该模型能在 Ampere、Ada Lovelace 和 RTX 5090 上运行。具体来说,vLLM 针对 gpt-oss 系列模型进行了优化,具有

  • 灵活的并行选项:模型可以分片到 2、4、8 个 GPU 上,扩展吞吐量。
  • 高性能注意力 (attention) 和 MoE 内核:注意力内核经过专门优化,以适应注意力“沉淀”(attention sinks)机制和滑动窗口形状。
  • 异步调度:通过将 CPU 操作与 GPU 操作重叠,优化以实现最大利用率和高吞吐量。

这是一份动态文档,我们欢迎贡献、修正和创建新的食谱!

快速入门

从预编译 wheel 安装

我们建议使用官方的 vLLM 0.10.2 版本作为起点。注意:运行 --tool-call-parser openai 需要 vLLM >= 0.10.2。创建一个新的虚拟环境并安装官方版本。

uv venv
source .venv/bin/activate
uv pip install vllm==0.10.2 --torch-backend=auto

我们还提供了一个包含所有内置依赖项的 Docker 容器。

docker run --gpus all \
    -p 8000:8000 \
    --ipc=host \
    vllm/vllm-openai:v0.10.2 \
    --model openai/gpt-oss-20b

A100

GPT-OSS 默认在 Ampere 设备上运行,使用 TRITON_ATTN 注意力后端和 Marlin MXFP4 MoE。

  • 可以启用 --async-scheduling 以获得更高的性能。注意:vLLM >= 0.11.1 改进了异步调度的稳定性,并提供了与结构化输出的兼容性。
# openai/gpt-oss-20b should run on a single A100
vllm serve openai/gpt-oss-20b --async-scheduling 

# gpt-oss-120b will fit on a single A100 (80GB), but scaling it to higher TP sizes can help with throughput
vllm serve openai/gpt-oss-120b --async-scheduling
vllm serve openai/gpt-oss-120b --tensor-parallel-size 2 --async-scheduling
vllm serve openai/gpt-oss-120b --tensor-parallel-size 4 --async-scheduling

H100 & H200

请参考 NVIDIA Blackwell & Hopper 硬件食谱 部分。

AMD

ROCm 在上市首日就支持 OpenAI gpt-oss-120b 或 gpt-oss-20b 模型在以下 3 种不同的 GPU 上运行,并提供预编译的 Docker 容器。

  • gfx950: MI350x 系列,rocm/vllm-dev:open-mi355-08052025
  • gfx942: MI300x/MI325 系列,rocm/vllm-dev:open-mi300-08052025
  • gfx1201: Radeon AI PRO R9700,rocm/vllm-dev:open-r9700-08052025

运行容器

alias drun='sudo docker run -it --network=host --device=/dev/kfd --device=/dev/dri --group-add=video --ipc=host --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --shm-size 32G -v /data:/data -v $HOME:/myhome -w /myhome'

drun rocm/vllm-dev:open-mi300-08052025

适用于 MI300x 和 R9700

export VLLM_ROCM_USE_AITER=1
export VLLM_USE_AITER_UNIFIED_ATTENTION=1
export VLLM_ROCM_USE_AITER_MHA=0

vllm serve openai/gpt-oss-120b --compilation-config '{"full_cuda_graph": true}' 

适用于 MI355x

# MoE preshuffle, fusion and Triton GEMM flags
export VLLM_USE_AITER_TRITON_FUSED_SPLIT_QKV_ROPE=1
export VLLM_USE_AITER_TRITON_FUSED_ADD_RMSNORM_PAD=1
export VLLM_USE_AITER_TRITON_GEMM=1
export VLLM_ROCM_USE_AITER=1
export VLLM_USE_AITER_UNIFIED_ATTENTION=1
export VLLM_ROCM_USE_AITER_MHA=0
export TRITON_HIP_PRESHUFFLE_SCALES=1

vllm serve openai/gpt-oss-120b --compilation-config '{"compile_sizes": [1, 2, 4, 8, 16, 24, 32, 64, 128, 256, 4096, 8192], "full_cuda_graph": true}' --block-size 64 

已知问题

  • 当遇到错误 The link interface of target "torch::nvtoolsext" contains: CUDA::nvToolsExt but the target was not found. 时,请仔细检查您的 PyTorch 版本是否带有 +cu128 后缀。
  • 如果输出是乱码,可能是因为您没有正确设置 CUDA_HOME。CUDA 版本需要大于或等于 12.8,并且安装和服务的 CUDA 版本必须相同。

用法

一旦 vllm serve 运行并显示 INFO: Application startup complete,您就可以使用 HTTP 请求或 OpenAI SDK 向以下端点发送请求。

  • /v1/responses 端点可以在链式思考 (chain-of-thought) 之间执行工具使用(浏览、Python、MCP)并提供最终响应。此端点利用 openai-harmony 库进行输入渲染和输出解析。状态化操作和完整流式 API 正在开发中。OpenAI 推荐使用 Responses API 来与此模型进行交互。
  • /v1/chat/completions 端点为该模型提供了一个熟悉的接口。不会调用任何工具,但推理和最终文本输出将结构化返回。您还可以在请求参数中设置 include_reasoning: false 参数以跳过将 CoT 作为输出的一部分。
  • /v1/completions 端点是一个简单的输入输出接口,没有任何类型的模板渲染。

所有端点都接受 stream: true 作为操作的一部分,以启用增量 token 流式传输。请注意,vLLM 目前尚未覆盖 Responses API 的全部功能,更多详情请参见下方的限制部分。

工具使用

gpt-oss 的一个主要功能是能够直接调用工具,称为“内置工具”。在 vLLM 中,我们提供了几个选项。

  • 默认情况下,我们通过 Docker 容器集成了参考库的浏览器(带有 ExaBackend)和演示 Python 解释器。要使用搜索后端,您需要获取 exa.ai 的访问权限,并将 EXA_API_KEY= 设置为环境变量。对于 Python,要么拥有 Docker,要么设置 PYTHON_EXECUTION_BACKEND=dangerously_use_uv 以允许模型生成的代码片段在同一台机器上执行。请注意,PYTHON_EXECUTION_BACKEND=dangerously_use_uv 需要 gpt-oss>=0.0.5
uv pip install gpt-oss

vllm serve ... --tool-server demo
  • 请注意,默认选项仅用于演示目的。对于生产环境,vLLM 本身可以作为 MCP 客户端连接到多个服务。这是一个 示例工具服务器,vLLM 可以与之协同工作,它们包装了演示工具。
mcp run -t sse browser_server.py:mcp
mcp run -t sse python_server.py:mcp

vllm serve ... --tool-server ip-1:port-1,ip-2:port-2

URL 应为 MCP SSE 服务器,这些服务器在服务器信息中实现了 instructions 并拥有文档齐全的工具。这些工具将被注入到模型的系统提示中,以便模型能够使用它们。

函数调用

vLLM 还支持调用用户定义的函数。请确保使用以下参数运行您的 gpt-oss 模型。

vllm serve ... --tool-call-parser openai --enable-auto-tool-choice

准确性评估面板

OpenAI 建议使用 gpt-oss 参考库进行评估。

首先,使用 vLLM 部署模型。

# Example deployment on 8xH100
vllm serve openai/gpt-oss-120b \
  --tensor_parallel_size 8 \
  --max-model-len 131072 \
  --max-num-batched-tokens 10240 \
  --max-num-seqs 128 \
  --gpu-memory-utilization 0.85 \
  --no-enable-prefix-caching

然后,使用 gpt-oss 运行评估。以下命令将运行所有 3 个推理努力级别。

mkdir -p /tmp/gpqa_openai
OPENAI_API_KEY=empty python -m gpt_oss.evals --model openai/gpt-oss-120b --eval gpqa --n-threads 128

要评估 AIME2025,请将 gpqa 更改为 aime25

这是我们在没有使用工具的情况下能够复现的分数,我们鼓励您也尝试复现!我们注意到数字在不同运行之间可能会略有差异,因此您可以多次运行评估以了解方差。为了进行快速的正确性检查,我们建议从低推理努力设置(--reasoning-effort low)开始,这应该在几分钟内完成。

模型:120B

推理努力 GPQA AIME25
65.3 51.2
72.4 79.6
79.4 93.0

模型:20B

推理努力 GPQA AIME25
56.8 38.8
67.5 75.0
70.9 85.8

NVIDIA Blackwell & Hopper 硬件食谱

本章包含更多关于在 NVIDIA Blackwell & Hopper 硬件上运行 gpt-oss-120b 和 gpt-oss-20b 的说明,以获得比快速入门章节中更高的性能优化。

拉取 Docker 镜像

拉取 vLLM v0.12.0 版本的 Docker 镜像。

pull_image.sh

# On x86_64 systems:
docker pull --platform linux/amd64 vllm/vllm-openai:v0.12.0
# On aarch64 systems:
# docker pull --platform linux/aarch64 vllm/vllm-openai:v0.12.0

docker tag vllm/vllm-openai:v0.12.0 vllm/vllm-openai:deploy

运行 Docker 容器

使用 Docker 镜像 vllm/vllm-openai:deploy 运行 Docker 容器。

run_container.sh

docker run -e HF_TOKEN="$HF_TOKEN" -e HF_HOME="$HF_HOME" --ipc=host --gpus all --entrypoint "/bin/bash" --rm -it vllm/vllm-openai:deploy

注意:如果需要,您可以使用 -v <local_path>:<path> 标志挂载其他目录和路径,例如挂载已下载的权重路径。

添加 -e HF_TOKEN="$HF_TOKEN" -e HF_HOME="$HF_HOME" 标志是为了使用您的 HuggingFace 令牌下载模型,并将下载的模型缓存到 $HF_HOME 中。有关这些环境变量的更多信息,请参阅 HuggingFace 文档;有关生成 HuggingFace 访问令牌的步骤,请参阅 HuggingFace 快速入门指南

准备配置文件

准备配置文件 YAML 文件以配置 vLLM。下方显示了 Blackwell 和 Hopper 架构的推荐配置文件。这些配置文件也已上传到 vLLM 食谱存储库。每个配置的解释将在“配置和参数”部分显示。

GPT-OSS_Blackwell.yaml

kv-cache-dtype: fp8
compilation-config: '{"pass_config":{"fuse_allreduce_rms":true,"eliminate_noops":true}}'
async-scheduling: true
no-enable-prefix-caching: true
max-cudagraph-capture-size: 2048
max-num-batched-tokens: 8192
stream-interval: 20

GPT-OSS_Hopper.yaml

async-scheduling: true
no-enable-prefix-caching: true
max-cudagraph-capture-size: 2048
max-num-batched-tokens: 8192
stream-interval: 20

以下是启用 EAGLE3 投机解码的配置文件 YAML。

GPT-OSS_EAGLE3_Blackwell.yaml

kv-cache-dtype: fp8
compilation-config: '{"pass_config":{"fuse_allreduce_rms":true,"eliminate_noops":true}}'
async-scheduling: true
no-enable-prefix-caching: true
max-cudagraph-capture-size: 2048
max-num-batched-tokens: 8192
stream-interval: 20
speculative-config: '{"model":"nvidia/gpt-oss-120b-Eagle3-v2","num_speculative_tokens":3,"method":"eagle3","draft_tensor_parallel_size":1}'

GPT-OSS_EAGLE3_Hopper.yaml

async-scheduling: true
no-enable-prefix-caching: true
max-cudagraph-capture-size: 2048
max-num-batched-tokens: 8192
stream-interval: 20
speculative-config: '{"model":"nvidia/gpt-oss-120b-Eagle3-v2","num_speculative_tokens":3,"method":"eagle3","draft_tensor_parallel_size":1}'

启动 vLLM 服务器

以下是一个使用 openai/gpt-oss-120b 模型启动 vLLM 服务器的示例命令。对于 GPT-OSS-20b,指令相同,只需将模型名称替换为 openai/gpt-oss-20b

launch_server.sh

# Set up a few environment variables for better performance for Blackwell architecture.
# They will be removed when the performance optimizations have been verified and enabled by default.
COMPUTE_CAPABILITY=$(nvidia-smi -i 0 --query-gpu=compute_cap --format=csv,noheader)
if [ "$COMPUTE_CAPABILITY" = "10.0" ]; then
    # Use FlashInfer MXFP4+MXFP8 MoE
    export VLLM_USE_FLASHINFER_MOE_MXFP4_MXFP8=1
    # Select the config file for Blackwell architecture.
    YAML_CONFIG="GPT-OSS_Blackwell.yaml"
else
    # Select the config file for Hopper architecture.
    YAML_CONFIG="GPT-OSS_Hopper.yaml"
    # vLLM v0.12.0 has a performance regression on Hopper GPUs for small concurrency
    # (see: https://github.com/vllm-project/vllm/issues/28894 ). Enable this environment
    # variable to fix the regression. This has been fixed in https://github.com/vllm-project/vllm/pull/30528
    # and the env var will no longer be needed in the next vLLM version.
    # export VLLM_MXFP4_USE_MARLIN=1
fi

# Launch the vLLM server
vllm serve openai/gpt-oss-120b \
  --config ${YAML_CONFIG} \
  --tensor-parallel-size 1 &

服务器设置完成后,客户端现在可以向服务器发送提示请求并接收结果。

配置与参数

您可以使用这些标志/配置指定服务器运行的 IP 地址和端口。

  • host:服务器的 IP 地址。默认情况下,它使用 127.0.0.1。
  • port:服务器监听的端口。默认情况下,它使用端口 8000。

以下是我们不建议更改或调整的配置标志

  • compilation-config:vLLM 编译阶段的配置。我们建议将其设置为 '{"pass_config":{"fuse_allreduce_rms":true,"eliminate_noops":true}}' 以启用 Blackwell 架构上所有必需的融合以获得最佳性能。但是,此功能尚不支持 Hopper 架构。
  • async-scheduling:启用异步调度以减少解码步骤之间的主机开销。我们建议始终添加此标志以获得最佳性能。注意:vLLM >= 0.11.1 改进了异步调度的稳定性,并提供了与结构化输出的兼容性。
  • no-enable-prefix-caching:禁用前缀缓存。如果使用合成数据集进行一致的性能测量,我们建议始终添加此标志。
  • max-cudagraph-capture-size:指定 cuda グラフ的最大大小。我们建议将其设置为 2048,以利用 cuda グラフ的优势,同时不使用过多的 GPU 内存。
  • stream-interval:输出 token 流式响应之间的间隔。我们建议将其设置为 20 以最大化吞吐量。

以下是一些您可以根据您的服务要求修改的可调参数

  • tensor-parallel-size:张量并行大小。增加此值将增加用于推理的 GPU 数量。
  • 将其设置为 1 以实现每个 GPU 的最佳吞吐量,并将其设置为 248 以实现更好的每个用户延迟。
  • max-num-batched-tokens:每个批次的最大令牌数。
  • 我们建议将其设置为 8192。如果序列具有较长的输入序列长度,增加此值可能会略微提高性能。
  • max-num-seqs:每个批次的最大序列数。
  • 默认情况下,在具有大内存大小的 GPU 上,此值设置为 1024 等大数字。
  • 如果实际并发较小,将其设置为与最大并发匹配的较小数字可能会提高性能并改善每个用户的延迟。
  • max-model-len:每个请求的总令牌数(包括输入令牌和输出令牌)的最大值。
  • 默认情况下,此值设置为模型支持的最大序列长度。
  • 如果实际输入+输出序列长度短于默认值,将其设置为较小值可能会提高性能。
  • 例如,如果最大输入序列长度为 1024 令牌,最大输出序列长度为 1024,则可以将其设置为 2048 以获得更好的性能。

有关如何调整这些可调参数以满足您的部署要求,请参阅“平衡吞吐量和延迟”部分。

性能基准测试

要进行性能基准测试,您可以使用 vllm bench serve 命令。

run_performance.sh

vllm bench serve \
  --host 0.0.0.0 \
  --port 8000 \
  --model openai/gpt-oss-120b \
  --trust-remote-code \
  --dataset-name random \
  --random-input-len 1024 \
  --random-output-len 1024 \
  --ignore-eos \
  --max-concurrency 1024 \
  --num-prompts 5120 \
  --save-result --result-filename vllm_benchmark_serving_results.json

标志的解释

  • --dataset-name:用于基准测试的数据集。我们这里使用 random 数据集。
  • --random-input-len:指定平均输入序列长度。
  • --random-output-len:指定平均输出序列长度。
  • --ignore-eos:当生成 eos(句尾)令牌时禁用提前返回。这确保了输出序列长度与我们的预期范围匹配。
  • --max-concurrency:最大并发请求数。我们建议将其与用于启动服务器的 --max-num-seqs 标志匹配。
  • --num-prompts:用于性能基准测试的提示总数。我们建议将其设置为 --max-concurrency 的至少五倍,以测量稳定状态性能。
  • --save-result --result-filename:性能基准测试结果的输出位置。

解读性能基准测试输出

vllm bench serve 命令的示例输出

============ Serving Benchmark Result ============
Successful requests:                     xxxxxx
Benchmark duration (s):                  xxx.xx
Total input tokens:                      xxxxxx
Total generated tokens:                  xxxxxx
Request throughput (req/s):              xxx.xx
Output token throughput (tok/s):         xxx.xx
Total Token throughput (tok/s):          xxx.xx
---------------Time to First Token----------------
Mean TTFT (ms):                          xxx.xx
Median TTFT (ms):                        xxx.xx
P99 TTFT (ms):                           xxx.xx
-----Time per Output Token (excl. 1st token)------
Mean TPOT (ms):                          xxx.xx
Median TPOT (ms):                        xxx.xx
P99 TPOT (ms):                           xxx.xx
---------------Inter-token Latency----------------
Mean ITL (ms):                           xxx.xx
Median ITL (ms):                         xxx.xx
P99 ITL (ms):                            xxx.xx
----------------End-to-end Latency----------------
Mean E2EL (ms):                          xxx.xx
Median E2EL (ms):                        xxx.xx
P99 E2EL (ms):                           xxx.xx
==================================================

关键指标的解释

  • Median Time to First Token (TTFT):从发送请求到生成第一个输出令牌的典型时间。
  • Median Time Per Output Token (TPOT):生成第一个令牌后生成每个令牌所需的典型时间。
  • Median Inter-Token Latency (ITL):一个输出令牌(或输出令牌)完成响应与下一个令牌完成响应之间的典型时间延迟。
  • 如果服务器命令中添加了 --stream-interval 20 标志,则 ITL 将是每 20 个输出 token 的完成时间。
  • Median End-to-End Latency (E2EL):从提交请求到收到响应的最终令牌的典型总时间。
  • Output token throughput:系统生成输出(已生成)令牌的速率。
  • Total Token Throughput:系统处理输入(提示)令牌和输出(已生成)令牌的总速率。

平衡吞吐量和延迟

在 LLM 推理中,“吞吐量”可以定义为每秒生成的令牌数(上面的 Output token throughput 指标)或每秒处理的令牌数(上面的 Total Token Throughput 指标)。这两个吞吐量指标高度相关。在比较不同的并行配置时,我们通常将吞吐量除以使用的 GPU 数量以获得“每 GPU 吞吐量”。每 GPU 吞吐量越高,服务相同数量的传入请求所需的 GPU 越少。

另一方面,“延迟”可以定义为从发送请求到生成第一个输出令牌的延迟(TTFT 指标),在生成第一个令牌后两个生成令牌之间的延迟(TPOT 指标),或者从发送请求到生成最终令牌的端到端延迟(E2EL 指标)。当输入(提示)序列长度远长于输出(生成)序列长度时,TTFT 对 E2EL 的影响更大,而在相反的情况下,TPOT 对 E2EL 的影响更大。

为了实现更高的吞吐量,来自多个请求的令牌必须批量处理,但这会增加延迟。因此,必须根据部署要求在吞吐量和延迟之间进行平衡。

GPT-OSS 的两个主要可调配置是 --tensor-parallel-size (TP) 和 --max-num-seqs (BS)。它们如何影响吞吐量和延迟可以总结如下:

  • 在相同的 BS 下,较高的 TP 通常会导致较低的延迟,但吞吐量也较低。
  • 在相同的 TP 大小下,较高的 BS 通常会导致较高的吞吐量,但延迟较差,但最大 BS 受加载权重后可用 GPU 内存(用于 kv-cache)的限制。
  • 因此,增加 TP(在相同 BS 下会降低吞吐量)可能允许运行更高的 BS(会增加吞吐量),净吞吐量增益/损失取决于模型和配置。

请注意,上述陈述假设客户端的并发设置(例如性能基准测试命令中的 --max-concurrency 标志)与服务器端的 --max-num-seqs (BS) 设置匹配。

以下是 B200 GPU 上不同吞吐量-延迟场景的推荐配置

  • 最大吞吐量:将 TP 设置为 1,并将 BS 增加到最大可能值,同时不超过 KV 缓存容量。
  • 最小延迟:将 TP 设置为 4 或 8,并将 BS 设置为满足延迟要求的较小值(如 8)。
  • 平衡:将 TP 设置为 2,并将 BS 设置为 128。

最后,另一个次要可调配置是 --max-num-batched-tokens 标志,它控制在一个前向迭代中可以批量处理多少令牌。我们建议将其设置为 8192,这在大多数情况下效果很好。将其增加到 16384 可能会导致吞吐量略高,TTFT 延迟更低,但 TPOT 延迟的分布更不均匀,因为一些输出令牌可能会在同一批次中与更多预填充阶段令牌一起生成。

已知限制

  • 在 H100 上使用张量并行大小为 1、默认 GPU 内存利用率和批量 token 时,会导致 CUDA Out-of-memory。运行 tp1 时,请提高您的 GPU 内存利用率或降低批量 token。
vllm serve openai/gpt-oss-120b --gpu-memory-utilization 0.95 --max-num-batched-tokens 1024
  • 在 H100 上运行 TP2 时,请将 GPU 内存利用率设置为低于 0.95,否则也会导致 OOM。
  • Responses API 目前存在一些限制;我们非常欢迎在 vLLM 中贡献和维护此服务。
  • 使用情况会计目前已损坏,仅返回全零。
  • 不支持注释(引用搜索结果中的 URL)。
  • 通过 max_tokens 进行的截断可能无法保留部分块。
  • 目前流式传输相当基础,例如:
  • 项目 ID 和索引需要更多工作。
  • 工具调用和输出不是正确流式传输,而是批量处理。
  • 缺少正确的错误处理。

故障排除

  • Blackwell 上的注意力沉淀 dtype 错误。
  ERROR 08-05 07:31:10 [multiproc_executor.py:559]     assert sinks.dtype == torch.float32, "Sinks must be of type float32"  
  **(VllmWorker TP0 pid=174579)** ERROR 08-05 07:31:10 [multiproc_executor.py:559]            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^  
  **(VllmWorker TP0 pid=174579)** ERROR 08-05 07:31:10 [multiproc_executor.py:559] AssertionError: Sinks must be of type float32

解决方案:请参考 Blackwell 部分,检查是否添加了相关的环境变量。

  • tl.language 未定义相关的 Triton 问题。

解决方案:确保您的环境中没有其他 Triton 安装(pytorch-triton 等)。

  • 遇到 openai_harmony.HarmonyError: error downloading or loading vocab file: failed to download or load vocab 错误。

解决方案:这是由 openai_harmony 代码中的一个 bug 引起的。可以通过提前下载 tiktoken 编码文件并设置 TIKTOKEN_ENCODINGS_BASE 环境变量来解决此问题。有关更多信息,请参见 此 GitHub issue

mkdir -p tiktoken_encodings
wget -O tiktoken_encodings/o200k_base.tiktoken "https://openaipublic.blob.core.windows.net/encodings/o200k_base.tiktoken"
wget -O tiktoken_encodings/cl100k_base.tiktoken "https://openaipublic.blob.core.windows.net/encodings/cl100k_base.tiktoken"
export TIKTOKEN_ENCODINGS_BASE=${PWD}/tiktoken_encodings

Harmony 格式支持

下方是 Harmony 格式的支持矩阵。

含义

  • ✅ = 完全兼容
  • ❌ = 不兼容
API 类型 基本文本生成 结构化输出 内置工具(带演示工具服务器) 内置工具(带 MCP) 函数调用
Response API
Response API(带后台模式)
Response API(带流式传输)
Chat Completion API
Chat Completion API(带流式传输)

如果您想使用离线推理,可以将 vLLM 视为一个 token 输入 token 输出的服务,并传入已使用 Harmony 格式化的 token。

对于函数调用,仅支持 tool_choice="auto"。