TellWorldAI 世界档案
问档案English

首页›实践›实践

实践

GLM-4.7-Flash 用 vLLM 部署

GLM-4.7-Flash 用 vLLM 部署:开思考模式并设官方推荐参数,配好推理解析器,再用四个工具函数实测工具调用链路。

GLM-4.7-Flash 是一个体积紧凑的推理模型,自带两个很多小模型没有的能力:可开关的思考模式和原生工具调用。配上 vLLM,它可以在本地变成一个「会思考、会调用工具」的 OpenAI 兼容服务。这篇从部署讲到参数,最后用两个容易答错的题目实测工具调用。Flash 后缀意味着这是 GLM 系列里主打性价比的小型号,推理能力齐全但显存门槛低,适合想在自己机器上体验完整推理能力的开发者。

模型和环境

vLLM 是高效的大模型推理和部署服务系统:PagedAttention 管理 KV 缓存减少显存浪费,连续批处理提升吞吐,内置 OpenAI 协议服务器,多卡支持分布式推理 [1]。对这次部署真正起作用的是其中两样:OpenAI 协议服务器让下游应用零改造接入,连续批处理让多用户并发时不至于排队。GLM-4.7-Flash 的参考环境是 Ubuntu 22.04、Python 3.12.3、CUDA 12.8、PyTorch 2.8.0 [1]。依赖只有两个,vllm 需要 0.10.0 以上,走清华镜像源安装 [1]。环境要求是比较新的组合:CUDA 12.8 和 PyTorch 2.8.0 都是比较新的版本,装之前先确认显卡驱动支持这个 CUDA 版本,否则会在运行时报错而不是安装时。

python -m pip install --upgrade pip
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

pip install modelscope
pip install vllm>=0.10.0

模型从 ModelScope 下载 [1]:

from modelscope import snapshot_download

model_dir = snapshot_download('ZhipuAI/GLM-4.7-Flash', cache_dir='your_model_dir', revision='master')

离线推理:思考模式怎么开

离线脚本是标准 vLLM 写法——LLM 引擎加 SamplingParams——但有几处 GLM 特有的细节 [1]:

from vllm import LLM, SamplingParams
from transformers import AutoTokenizer
import os
import json

# 自动下载模型时,指定使用modelscope; 否则,会从HuggingFace下载
os.environ['VLLM_USE_MODELSCOPE']='True'

def get_completion(prompts, model, tokenizer=None, temperature=0.6, top_p=0.95, top_k=20, min_p=0, max_tokens=4096, max_model_len=8192):
    stop_token_ids = [151645, 151643]
    # 创建采样参数。temperature 控制生成文本的多样性,top_p 控制核心采样的概率,top_k 通过限制候选词的数量来控制生成文本的质量和多样性, min_p 通过设置概率阈值来筛选候选词,从而在保证文本质量的同时增加多样性
    sampling_params = SamplingParams(temperature=temperature, top_p=top_p, top_k=top_k, min_p=min_p, max_tokens=max_tokens, stop_token_ids=stop_token_ids)  # max_tokens 用于限制模型在推理过程中生成的最大输出长度
    # 初始化 vLLM 推理引擎
    llm = LLM(model=model, tokenizer=tokenizer, max_model_len=max_model_len,trust_remote_code=True, tensor_parallel_size=4)  # max_model_len 用于限制模型在推理过程中可以处理的最大输入和输出长度之和。
    outputs = llm.generate(prompts, sampling_params)
    return outputs

两个细节值得停一下。采样参数比常见的 temperature 加 top_p 多了一层:top_k 限制每一步参与竞争的候选词数量,min_p 按概率阈值筛掉低质量候选——三层参数叠起来,质量和多样性才能同时保住 [1]。另外 tensor_parallel_size=4 说明示例按四卡并行配置,单卡环境记得改回 1 [1]。

提示词用分词器的聊天模板格式化,思考模式的开关就在这次调用里 [1]:

if __name__ == "__main__":
    # 初始化 vLLM 推理引擎
    model='/root/autodl-fs/ZhipuAI/GLM-4.7-Flash' # 指定模型路径
    tokenizer = AutoTokenizer.from_pretrained(model) # 加载分词器

    prompt = "给我一个关于大模型的简短介绍。"
    messages = [
        {"role": "user", "content": prompt}
    ]
    text = tokenizer.apply_chat_template(
        messages,
        tokenize=False,
        add_generation_prompt=True,
        enable_thinking=True  # 是否开启思考模式,默认为 True
    )

    outputs = get_completion(text, model, tokenizer=None, temperature=0.6, top_p = 0.95, top_k=20, min_p=0)  # 对于思考模式,官方建议使用以下参数:temperature = 0.6,TopP = 0.95,TopK = 20,MinP = 0。

思考模式的官方推荐参数是:temperature 0.6、TopP 0.95、TopK 20、MinP 0 [1]。关掉思考只改一个词——enable_thinking=False——简单请求用不上思考过程时可以省下这部分 token [1]。要不要关,可以用一个简单标准:答案对错不重要、只要格式对的任务(改写、翻译、分类)关掉;需要推导、计算、多步规划的题开着。开着的代价不只是 token,还有延迟——思考几千 token 才开始输出答案,交互场景里感知很明显。

输出循环直接打印生成结果 [1]:

    # 输出是一个包含 prompt、生成文本和其他信息的 RequestOutput 对象列表。
    # 打印输出。
    for output in outputs:
        prompt = output.prompt
        generated_text = output.outputs[0].text
        print(f"Prompt: {prompt!r}, \nResponse: {generated_text!r}")

响应分两部分:<think> 和 </think> 包住的是思考过程,</think> 之后才是最终答案 [1]。示例运行里能看到模型对「简短介绍大模型」这个请求规划、起草、修改了七轮才落笔——这种可见的迭代过程,正是难提示词开思考、简单请求关思考的判断依据。

起 API 服务:推理解析与工具解析

GLM-4.7-Flash 兼容 OpenAI 协议,vllm serve 一条命令起服务:默认 http://localhost:8000,一次托管一个模型,带模型列表、completions、chat completions 三类端点 [1]。completions 面向文章、故事、邮件这类文本生成,chat completions 面向聊天机器人和对话系统 [1]。这条启动命令里的解析器参数是重点 [1]:

vllm serve /root/autodl-fs/ZhipuAI/GLM-4.7-Flash \
     --tensor-parallel-size 4 \
     --speculative-config.method mtp \
     --speculative-config.num_speculative_tokens 1 \
     --tool-call-parser glm47 \
     --reasoning-parser glm45 \
     --enable-auto-tool-choice \
     --served-model-name glm-4.7-flash

开启 --enable-reasoning 时,--reasoning-parser 是必填项:推理模型会在输出里附带一个额外的 reasoning_content 字段,装着导向最终结论的推理步骤,配好解析器后这些内容会被正确提取和格式化 [1]。这一步解决的是推理模型接入应用的老大难:思考内容和答案混在同一串文本里,客户端只能靠正则切分,模型换个写法就切错;服务端解析器把这件事标准化了,reasoning 和 content 各归各位。两行 speculative-config 启用 MTP(多 token 预测)投机解码来加速生成 [1]。投机解码的原理是先小步快跑猜几个 token 再验证,猜对了就赚回时间;GLM 系列模型自带 MTP 模块,所以这个加速不需要额外模型。

curl 测试沿用推理模型的两个惯例——提示词加 <think>\n 后缀、temperature 设 0 [1]:

curl http://localhost:8000/v1/completions \
    -H "Content-Type: application/json" \
    -d '{
        "model": "glm-4.7-flash",
        "prompt": "我想问你,5的阶乘是多少?<think>\n",
        "max_tokens": 1024,
        "temperature": 0
    }'

返回的文本里思考和答案混在一起,答案是 120,这次调用用了 11 个 prompt token、421 个 completion token [1]。换成 Python 客户端走 chat 接口就干净多了:最终答案在 content 字段,思考步骤单独放在 reasoning 字段——服务端配好解析器后,客户端不用再写正则 [1]:

from openai import OpenAI
openai_api_key = "sk-xxx" # 随便填写,只是为了通过接口参数校验
openai_api_base = "http://localhost:8000/v1"

client = OpenAI(
    api_key=openai_api_key,
    base_url=openai_api_base,
)

chat_outputs = client.chat.completions.create(
    model="glm-4.7-flash",
    messages=[
        {"role": "user", "content": "什么是算法?"},
    ]
)
print(chat_outputs)

工具调用实测

工具调用是小模型经常翻车的地方,值得专门测。示例定义了四个 Python 函数——加法、乘法、比较大小、数字母——每个函数配一份带类型和必填字段的工具描述 [1]。工具描述的质量直接决定模型选得准不准:函数名用英文动词、description 写清「做什么、参数是什么意思」,模型的选择准确率会明显不同。客户端把用户问题和工具列表一起发过去,读回模型的选择 [1]:

def function_call_playground(prompt):
    messages = [{'role': 'user', 'content': prompt}]
    response = client.chat.completions.create(
        model="glm-4.7-flash",
        messages = messages,
        temperature=0.01,
        top_p=0.95,
        stream=False,
        tools=tools)

    # print(response)
    func1_name = response.choices[0].message.tool_calls[0].function.name
    func1_args = response.choices[0].message.tool_calls[0].function.arguments
    func1_out = eval(f'{func1_name}(**{func1_args})')

注意这里 temperature 压到了 0.01——选工具要的是确定性,不是创造力 [1]。函数执行完后,把助手的工具调用消息和执行结果都追加回对话,再请求一次让模型把原始结果转成人话 [1]:

    messages.append(response.choices[0].message)
    messages.append({
        'role': 'tool',
        'content': f'{func1_out}',
        'tool_call_id': response.choices[0].message.tool_calls[0].id
    })
    # print(messages)
    response = client.chat.completions.create(
        model="glm-4.7-flash",
        messages=messages,
        temperature=0.01,
        top_p=0.95,
        stream=False,
        tools=tools)
    return response.choices[0].message.content

两个测试题是刻意挑的:「strawberry 中有多少个 r」和「9.11 和 9.9 哪个小」——这两类问题推理模型凭直觉经常答错。走工具链路的结果都对:r 出现 3 次,9.11 比 9.9 小 [1]。整个请求处理过程中,API 后端都会打印对应的日志和统计信息,排查问题时盯着服务端日志看 [1]。

常见问题

  1. 单卡用户照抄 tensor_parallel_size=4 会直接报错或占满显存,改回 1;
  2. 忘记 --reasoning-parser 时开了 --enable-reasoning,服务启动就会提示缺参数;
  3. 示例里用 eval 执行模型点名的函数,演示没问题,生产环境务必换成函数名到函数对象的字典映射——eval 执行任意字符串是安全风险;
  4. 思考内容出现在 content 里而不是 reasoning 字段,通常是没配 --reasoning-parser 或解析器型号写错。

本文改编自 Datawhale 开源教程《self-llm》的 GLM-4.7-Flash vLLM 部署一节[1],原文以 Apache-2.0 许可证发布。

来源

  1. 1
    01-GLM-4.7-Flash-vLLM 部署调用 | self-llmDatawhale self-llm (Apache-2.0)

引用本页: GLM-4.7-Flash 用 vLLM 部署. TellWorld, https://www.tellworld.net/zh/practice/practice-glm-4-7-flash-vllm. 更新于 2026-11-14

相关动态