读这篇文章假设已经读过大模型部署

部署一下 GLM-4.7-Flash
https://huggingface.co/zai-org/GLM-4.7-Flash

首先,准备 vllm 环境,vllm 是大模型推理的框架之一。

环境准备

venv、pip、vllm

# 安装 venv 
sudo apt install python3-venv -y
# 初始化 venv 环境
python3 -m venv vllm-env
cd vllm-env/
source vllm-env/bin/activate
pip install --upgrade pip
# 安装 vllm,后面要使用 vllm 作为模型推理使用 GLM-4.7 权重
pip install vllm
# ... ... 等待下载后出现 Successfully installed  ... 安装完成
# 检测是否可用 https://docs.vllm.ai
vllm -h 

下载GLM-4.7-Flash

加速下载HF_XET_HIGH_PERFORMANCE

# 配置镜像站,如果已科学可忽略
export HF_ENDPOINT=https://hf-mirror.com

# 开启多线程下载 
export HF_XET_HIGH_PERFORMANCE=1

hf  download zai-org/GLM-4.7-Flash

默认下载路径

du -s -h  ~/.cache/huggingface/hub/models--zai-org--GLM-4.7-Flash/
59G     /root/.cache/huggingface/hub/models--zai-org--GLM-4.7-Flash/

启动GLM-4.7-Flash

启动命令

可以尝试先启动,如果有环境问题往下看
我有两张显卡,这里配置 --tensor-parallel-size 2
显存不多,限制了context --max-model-len 32768
参数作用文末有写
–reasoning-parser glm45
–tool-call-parser glm47
–enable-auto-tool-choice

vllm serve zai-org/GLM-4.7-Flash \
    --host 0.0.0.0 \
    --port 8099 \
    --tensor-parallel-size 2 \
    --max-model-len 32768 \
    --gpu-memory-utilization 0.9 \
    --served-model-name glm-4.7-flash

近60G 的模型启动需要几分钟,日志中看到相关的 starting server 标识 则启动成功。

APIServer pid=1034591) INFO 06-02 19:34:03 [api_server.py:596] Starting vLLM server on http://0.0.0.0:8099
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:37] Available routes are:
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /openapi.json, Methods: HEAD, GET
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /docs, Methods: HEAD, GET
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /docs/oauth2-redirect, Methods: HEAD, GET
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /redoc, Methods: HEAD, GET
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /tokenize, Methods: POST
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /detokenize, Methods: POST
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /load, Methods: GET
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /version, Methods: GET
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /health, Methods: GET
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /metrics, Methods: GET
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /v1/models, Methods: GET
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /ping, Methods: GET
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /ping, Methods: POST
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /invocations, Methods: POST
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /v1/chat/completions, Methods: POST
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /v1/chat/completions/batch, Methods: POST
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /v1/responses, Methods: POST
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /v1/responses/{response_id}, Methods: GET
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /v1/responses/{response_id}/cancel, Methods: POST
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /v1/completions, Methods: POST
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /v1/messages, Methods: POST
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /v1/messages/count_tokens, Methods: POST
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /inference/v1/generate, Methods: POST
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /scale_elastic_ep, Methods: POST
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /is_scaling_elastic_ep, Methods: POST
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /generative_scoring, Methods: POST
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /v1/chat/completions/render, Methods: POST
(APIServer pid=1034591) INFO 06-02 19:34:03 [launcher.py:46] Route: /v1/completions/render, Methods: POST
(APIServer pid=1034591) INFO:     Started server process [1034591]
简单验证
查看模型列表
curl --noproxy '*' http://127.0.0.1:8099/v1/models

请求返回

{
    "object": "list",
    "data": [
        {
            "id": "glm-4.7-flash",
            "object": "model",
            "created": 1780401515,
            "owned_by": "vllm",
            "root": "zai-org/GLM-4.7-Flash",
            "parent": null,
            "max_model_len": 32768,
            "permission": [
                {
                    "id": "modelperm-8aaff353c7c2a8da",
                    "object": "model_permission",
                    "created": 1780401515,
                    "allow_create_engine": false,
                    "allow_sampling": true,
                    "allow_logprobs": true,
                    "allow_search_indices": false,
                    "allow_view": true,
                    "allow_fine_tuning": false,
                    "organization": "*",
                    "group": null,
                    "is_blocking": false
                }
            ]
        }
    ]
}
QA

stream 可以指定为 true,最终他的返回结果与 ollama 有一些差异,返回的结构是 openApi 格式

curl --noproxy '*' http://127.0.0.1:8099/v1/chat/completions     -H "Content-Type: application/json"     -d '{
      "model": "glm-4.7-flash",
      "messages": [
        {"role": "user", "content": "你好,请用三句话介绍你自己"}
      ],
      "stream": false
    }'

返回

{
    "id": "chatcmpl-8a9c21acdfd79df3",
    "object": "chat.completion",
    "created": 1780401656,
    "model": "glm-4.7-flash",
    "choices": [
        {
            "index": 0,
            "message": {
                "role": "assistant",
                "content": "1. **识别用户的核心请求:**用户希望我(AI)用三句话介绍我自己。\n\n2. **分析约束条件:**\n    *   主题:自我介绍(AI助手/LangGPT)。\n    *   格式:正好三句话。\n    *   语言:中文(提示词的暗示)。\n\n3. **起草初步构思(内心独白/尝试):**\n    *   *草稿 1:* 我是一个由Z.ai开发的AI语言模型。我可以回答问题和生成文本。我希望通过交流帮助到你。(很好,标准,准确)。\n    *   *草稿 2:* 你好,我是GLM,一个大型语言模型。我没有情感但我可以处理信息。如果你想聊天或者需要帮助,随时叫我。(稍微随意一点)。\n    *   *草稿 3:* 我是GLM,一个由智谱AI训练的大语言模型。我可以协助你解答问题、创作内容或进行各种语言交流。很高兴能通过文字与你对话,期待为你提供帮助。(礼貌且专业)。\n\n4. **选择最佳方案:**草稿 3 平衡了身份、功能和建议的行动。简单直接。\n\n5. **润色选定的方案(中文):**\n    *   第1句:我是由Z.ai训练的大语言模型,名为GLM。(我是一名由Z.ai训练的语言模型,名字叫GLM。)\n    *   第2句:我可以回答问题、撰写文案,并进行各类语言交流。(我可以回答问题、撰写文案,并参与各种语言交流。)\n    *   第3句:很高兴能为您提供帮助,请随时告诉我您想知道什么。(很高兴能为您提供帮助,请随时告诉我您想知道什么。)\n\n6. **最终润色(对照约束条件检查):**\n    *   是否有三句话?是。\n    *   是否为自我介绍?是。\n    *   语言是否自然?是。\n\n7. **生成最终输出:**(清晰地呈现句子)。\n\n    我是Z.ai训练的大语言模型GLM。我可以回答问题、撰写文案,并参与各类语言交流。很高兴能为您提供帮助,请随时告诉我您想知道什么。</think>我是Z.ai研发的大语言模型GLM。我可以回答问题、撰写文案,并参与各类语言交流。很高兴能为您提供帮助,请随时告诉我您想知道什么。",
                "refusal": null,
                "annotations": null,
                "audio": null,
                "function_call": null,
                "tool_calls": [],
                "reasoning": null
            },
            "logprobs": null,
            "finish_reason": "stop",
            "stop_reason": 154827,
            "token_ids": null,
            "routed_experts": null
        }
    ],
    "service_tier": null,
    "system_fingerprint": "vllm-0.22.0-tp2-5b0f4813",
    "usage": {
        "prompt_tokens": 13,
        "total_tokens": 497,
        "completion_tokens": 484,
        "prompt_tokens_details": null
    },
    "prompt_logprobs": null,
    "prompt_token_ids": null,
    "prompt_text": null,
    "kv_transfer_params": null
}
环境问题解决
# 这里遇到了一堆环境问题,最终解决办法是将错误贴给 codex 后给出修复命令
# 修复环境后要清掉之前用错误 CUDA 编译过的缓存,然后重新启动 vLLM:
######### rm -rf /root/.cache/flashinfer  #########

pip install nvidia-cuda-nvcc-cu12==12.4.131 \
    -i https://mirrors.aliyun.com/pypi/simple \
    --trusted-host mirrors.aliyun.com

# 依旧是修复环境问题
pip install -U nvidia-cuda-nvcc nvidia-cuda-runtime nvidia-cuda-nvrtc nvidia-cuda-cupti \
    -i https://mirrors.aliyun.com/pypi/simple \
    --trusted-host mirrors.aliyun.com

export VLLM_USE_FLASHINFER_SAMPLER=0

pip install -U --force-reinstall 'cuda-toolkit[nvcc,nvrtc,cudart,cupti]==13.0.2' \
    -i https://mirrors.aliyun.com/pypi/simple \
    --trusted-host mirrors.aliyun.com

# 配置 nvcc 环境变量
find /root/vllm-env/vllm-env/lib/python3.12/site-packages/nvidia -name nvcc -type f
  find /root/vllm-env/vllm-env/lib/python3.12/site-packages/nvidia -name cuda_runtime.h -type f
  find /root/vllm-env/vllm-env/lib/python3.12/site-packages/nvidia -name libcudart.so* -type f
/root/vllm-env/vllm-env/lib/python3.12/site-packages/nvidia/cu13/bin/nvcc
/root/vllm-env/vllm-env/lib/python3.12/site-packages/nvidia/cu13/include/cuda_runtime.h
/root/vllm-env/vllm-env/lib/python3.12/site-packages/nvidia/cu13/lib/libcudart.so.13

export CUDA_HOME=/root/vllm-env/vllm-env/lib/python3.12/site-packages/nvidia/cu13
export PATH="$CUDA_HOME/bin:$PATH"
export CPATH="$CUDA_HOME/include"
export LIBRARY_PATH="$CUDA_HOME/lib"
export LD_LIBRARY_PATH="$CUDA_HOME/lib"

# 检查环境版本
which nvcc
  nvcc --version
  python -c "import torch; print(torch.__version__, torch.version.cuda)"
/root/vllm-env/vllm-env/lib/python3.12/site-packages/nvidia/cu13/bin/nvcc
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2025 NVIDIA Corporation
Built on Wed_Aug_20_01:58:59_PM_PDT_2025
Cuda compilation tools, release 13.0, V13.0.88
Build cuda_13.0.r13.0/compiler.36424714_0
2.11.0+cu130 13.0

# 版本对齐
torch: 2.11.0+cu130
torch CUDA: 13.0
nvcc: 13.0

参数补充

–reasoning-parser glm45
–tool-call-parser glm47
–enable-auto-tool-choice

这三个参数都是 vLLM 的 OpenAI-compatible API 输出解析/工具调用相关参数,不是模型加载必需参数。

  --reasoning-parser glm45

  作用:把模型输出里的“思考过程”解析成 OpenAI 风格的 reasoning 字段。

  有些 reasoning 模型会输出类似:

  <think>这里是思考过程</think>
  最终答案

  或者厂商自定义的 thinking 格式。

  --reasoning-parser glm45 告诉 vLLM:

  按 GLM-4.5/GLM 系列的 reasoning 格式去解析模型输出

  理想情况下返回会类似:

  {
    "message": {
      "content": "最终答案",
      "reasoning": "中间思考过程"
    }
  }

  但如果模型本次没有按 parser 期望的格式输出,vLLM 就解析不出来,reasoning 可能还是 null,思考文本会混在 content 里。

  --tool-call-parser glm47

  作用:解析 GLM-4.7 的工具调用格式。

  比如你给模型传 tools:

  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_weather",
        "parameters": {...}
      }
    }
  ]

  模型可能会生成一段它自己的工具调用文本。
  --tool-call-parser glm47 负责把这段文本转换成标准 OpenAI-compatible 的:

  "tool_calls": [
    {
      "type": "function",
      "function": {
        "name": "get_weather",
        "arguments": "{...}"
      }
    }
  ]

  如果不加这个 parser,模型可能仍然会输出工具调用内容,但它可能只是普通文本,不会变成标准 tool_calls 字段。

  --enable-auto-tool-choice

  作用:允许模型自动决定是否调用工具。

  OpenAI-compatible API 里有:

  "tool_choice": "auto"

  意思是:

  模型自己判断这次要不要调用工具

  vLLM 默认不一定允许自动工具选择,所以要加:

  --enable-auto-tool-choice

  通常它要和:

  --tool-call-parser glm47

  一起使用。

  三者关系

  --reasoning-parser glm45
    负责解析“思考过程”

  --tool-call-parser glm47
    负责解析“工具调用”

  --enable-auto-tool-choice
    允许模型自动选择工具调用

  它们不会显著改变模型能力,主要影响 API 返回结构。

  你现在的情况是:

  模型会输出分析过程
  但 reasoning 字段是 null

  说明模型输出没有匹配 glm45 parser 期望的 reasoning 格式,或者当前调用方式没有触发独立 reasoning 格式。
Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐