欢迎光临
我们一直在努力

在DGX-Spark上多模态模型gemma-4-31B-it vLLM部署

模型:gemma-4-31B-it gemma-4-31B-it

URL:http://localhost:8005/

model = "gemma-4-31b"

日志查看docker logs -f gemma4-vllm

1 部署

1步:先从modelscope上下载模型

进入spark目录:/home/admin/models/modelscope/
git clone https://www.modelscope.cn/google/gemma431Bit.git

2步:拉取gemma4cu130镜像
docker pull vllm/vllmopenai:gemma4cu130

docker pull docker.1ms.run/vllm/vllmopenai:gemma4cu130

3步:部署gemma431Bit
docker run d \\
gpus all \\
name gemma4vllm \\
restart unlessstopped \\
v /home/admin/models:/home/admin/models \\
p 8005:30000 \\
docker.1ms.run/vllm/vllmopenai:gemma4cu130 \\
model /home/admin/models/modelscope/gemma431Bit \\
servedmodelname gemma431b \\
enableautotoolchoice \\
toolcallparser pythonic \\
reasoningparser gemma4 \\
gpumemoryutilization 0.70 \\
host 0.0.0.0 \\
port 30000 \\
kvcachedtype fp8 \\
loadformat safetensors \\
enableprefixcaching \\
enablechunkedprefill \\
maxmodellen 262144 \\
maxnumseqs 4 \\
maxnumbatchedtokens 8192

4步:当容器停止后,重新启动即可

补充:

 vLLM 部署 Gemma 4 模型的 Docker 命令中每个参数的含义:

Docker 基础参数
参数含义
-d 后台运行(detached mode),容器在后台运行,不占用当前终端
–gpus all 启用所有 GPU,让容器可以访问主机的所有 NVIDIA GPU
–name gemma4-vllm 容器名称,方便后续管理(如 docker stop gemma4-vllm)
–restart unless-stopped 重启策略:除非手动停止,否则容器崩溃或主机重启后自动重启
-v /home/admin/models:/home/admin/models 卷挂载:将主机的模型目录映射到容器内相同路径,实现模型持久化
-p 8005:30000 端口映射:将主机的 8005 端口映射到容器的 30000 端口
vLLM 服务参数
参数含义
–model /home/admin/models/modelscope/gemma-4-31B-it 模型路径,指定 Gemma 4 31B 指令微调版的位置
–served-model-name gemma-4-31b 对外暴露的模型名称,API 调用时使用的标识名
–enable-auto-tool-choice 启用自动工具选择,让模型自动决定是否调用工具
–tool-call-parser pythonic 工具调用解析器格式,使用 Python 风格的工具调用格式
–reasoning-parser gemma4 推理解析器,专门用于解析 Gemma 4 模型的推理输出格式
–gpu-memory-utilization 0.70 GPU 内存使用率上限,限制使用 70% 的显存,预留空间给其他进程
–host 0.0.0.0 监听地址,绑定到所有网络接口,允许外部访问
–port 30000 服务端口,容器内部监听端口(与 Docker 映射的 30000 对应)
–kv-cache-dtype fp8 KV 缓存数据类型,使用 8 位浮点量化,减少显存占用
–load-format safetensors 模型加载格式,使用 SafeTensors 格式(更安全、加载更快)
–enable-prefix-caching 启用前缀缓存,对相同前缀的输入复用 KV 缓存,加速推理
–enable-chunked-prefill 启用分块预填充,将长输入分块处理,减少显存峰值占用
–max-model-len 262144 最大上下文长度,支持 262,144 tokens(约 20 万字)
–max-num-seqs 4 最大并发序列数,同时处理 4 个请求序列
–max-num-batched-tokens 8192 最大批处理 token 数,每个批次最多处理 8192 个 token
关键优化点总结
  • 显存优化:fp8 量化 + 70% 显存限制 + 分块预填充,适合大模型部署
  • 性能优化:前缀缓存 + SafeTensors 格式,提升重复查询和加载速度
  • 功能特性:支持工具调用(Tool Calling)和思维链解析,适配 Gemma 4 原生能力
  • 长上下文:26万 token 支持,适合长文档处理
  • 镜像说明

    docker.1ms.run/vllm/vllm-openai:gemma4-cu130 是专门为 Gemma 4 优化的镜像:

    • cu130 表示基于 CUDA 13.0
    • 预装了 Gemma 4 所需的依赖和补丁

    部署后,你可以通过 http://<服务器IP>:8005 访问 OpenAI 兼容的 API 接口。

    2 测试接口健康

    # 请求
    curl http://localhost:8005/v1/models

    # 响应:
    {
    "object": "list",
    "data": [
    {
    "id": "gemma-4-31b",
    "object": "model",
    "created": 1775196908,
    "owned_by": "vllm",
    "root": "/home/admin/models/modelscope/gemma-4-31B-it",
    "parent": null,
    "max_model_len": 262144,
    "permission": [
    {
    "id": "modelperm-a344e56a847117e2",
    "object": "model_permission",
    "created": 1775196908,
    "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
    }
    ]
    }
    ]
    }

    3 测试

    # 请求
    curl http://localhost:8005/v1/chat/completions \\
    H "Content-Type: application/json" \\
    d '{
    "model": "gemma-4-31b",
    "messages": [
    {
    "role": "system",
    "content": "你是一个helpful的AI助手。"
    },
    {
    "role": "user",
    "content": "你好,介绍自己。"
    }
    ],
    "temperature": 0.7,
    "max_tokens": 1024
    }'
    # 响应
    {
    "id": "chatcmpl-8b42bfc9c3dc3d4c",
    "object": "chat.completion",
    "created": 1775197098,
    "model": "gemma-4-31b",
    "choices": [
    {
    "index": 0,
    "message": {
    "role": "assistant",
    "content": "你好!很高兴为你服务。\\n\\n我是一个由 Google 训练的大型语言模型。你可以把我当作一个**全能的智能助手**,我旨在通过处理和生成文本,帮助用户高效地完成各种任务。\\n\\n**我能为你做些什么?**\\n\\n1. **回答问题**:无论是科学常识、历史文化、编程技术,还是日常生活中的小疑问,我都可以为你提供详细的解答。\\n2. **文字创作**:我可以帮你写邮件、周报、故事、诗歌、论文大纲,或者润色你的文章。\\n3. **语言翻译**:我精通多种语言,可以帮你进行流畅的互译。\\n4. **逻辑分析与编程**:我可以帮你编写代码(多种语言)、调试 Bug,或者分析复杂的问题并提供解决方案。\\n5. **总结与提取**:如果你有长篇文章没时间看,我可以帮你快速总结核心观点。\\n6. **创意启发**:当你没有灵感时,我可以帮你进行头脑风暴,提供各种创意点子。\\n\\n**我的特点:**\\n\\n* **耐心且客观**:我没有情绪,会尽可能客观地为你提供信息。\\n* **学习能力强**:我基于海量的数据训练,知识面非常广泛。\\n* **高效快捷**:我可以瞬间处理大量信息并给出反馈。\\n\\n**怎么与我更好地协作?**\\n\\n如果你能给我**更具体、更清晰的指令(Prompt)**,我给出的答案会更精准。例如,比起说“帮我写个计划”,说“请帮我写一个为期两周的东京旅游计划,预算5000元,侧重于美食和动漫”会效果更好。\\n\\n**那么,现在有什么我可以帮你的吗?**",
    "refusal": null,
    "annotations": null,
    "audio": null,
    "function_call": null,
    "tool_calls": [
    ],
    "reasoning": null
    },
    "logprobs": null,
    "finish_reason": "stop",
    "stop_reason": 106,
    "token_ids": null
    }
    ],
    "service_tier": null,
    "system_fingerprint": null,
    "usage": {
    "prompt_tokens": 43,
    "total_tokens": 430,
    "completion_tokens": 387,
    "prompt_tokens_details": null
    },
    "prompt_logprobs": null,
    "prompt_token_ids": null,
    "kv_transfer_params": null
    }

    4 测试图片理解

    # 请求
    curl http://localhost:8005/v1/chat/completions \\
    H "Content-Type: application/json" \\
    d '{
    "model": "gemma-4-31b",
    "messages": [
    {
    "role": "user",
    "content": [
    {
    "type": "image_url",
    "image_url": {
    "url": "https://www.171host.com/wp-content/uploads/2026/05/20260506092428-69fb08cc05e78.jpg"
    }
    },
    {
    "type": "text",
    "text": "这张图片里有什么?"
    }
    ]
    }
    ],
    "max_tokens": 512
    }'

    # 响应:
    {
    "id": "chatcmpl-96634f63e8a7aabe",
    "object": "chat.completion",
    "created": 1775196591,
    "model": "gemma-4-31b",
    "choices": [
    {
    "index": 0,
    "message": {
    "role": "assistant",
    "content": "这张图片展现了一个宁静的自然景观。\\n\\n画面中心是一条由浅色木板铺成的**栈道(木栈道)**,它从前景一直延伸到远方,引导观众的视线向深处移动。\\n\\n栈道两旁是茂盛的**绿色草地或湿地**,长满了高高的绿草。在背景中,可以看到一排低矮的**树木和灌木丛**,将草地与天空分隔开。\\n\\n上方是广阔的**蓝色天空**,点缀着轻盈的白色卷云和散落的云朵,光线明亮,给人一种开阔、清新且平静的感觉。",
    "refusal": null,
    "annotations": null,
    "audio": null,
    "function_call": null,
    "tool_calls": [
    ],
    "reasoning": null
    },
    "logprobs": null,
    "finish_reason": "stop",
    "stop_reason": 106,
    "token_ids": null
    }
    ],
    "service_tier": null,
    "system_fingerprint": null,
    "usage": {
    "prompt_tokens": 281,
    "total_tokens": 427,
    "completion_tokens": 146,
    "prompt_tokens_details": null
    },
    "prompt_logprobs": null,
    "prompt_token_ids": null,
    "kv_transfer_params": null
    }

    5 测试视频理解

    Gemma 4 的视频理解通过逐帧抽帧方式实现,将视频关键帧转为多张图片传入

    注意: 视频理解目前 vLLM 不支持直接传视频文件,需要手动抽帧后以多图片形式传入。帧数建议控制在 5~10 帧,避免超出 token 限制。

    # 用 ffmpeg 从视频抽取关键帧(每秒1帧,取前5帧)
    ffmpeg -i /path/to/video.mp4 -vf "fps=1" -frames:v 5 /tmp/frame%d.jpg

    # 将每帧转为 base64
    FRAME1=$(base64 -w 0 /tmp/frame1.jpg)
    FRAME2=$(base64 -w 0 /tmp/frame2.jpg)
    FRAME3=$(base64 -w 0 /tmp/frame3.jpg)
    FRAME4=$(base64 -w 0 /tmp/frame4.jpg)
    FRAME5=$(base64 -w 0 /tmp/frame5.jpg)

    curl http://localhost:8005/v1/chat/completions \\
    -H "Content-Type: application/json" \\
    -d "{
    \\"model\\": \\"gemma-4-31b\\",
    \\"messages\\": [
    {
    \\"role\\": \\"user\\",
    \\"content\\": [
    {\\"type\\": \\"image_url\\", \\"image_url\\": {\\"url\\": \\"data:image/jpeg;base64,${FRAME1}\\"}},
    {\\"type\\": \\"image_url\\", \\"image_url\\": {\\"url\\": \\"data:image/jpeg;base64,${FRAME2}\\"}},
    {\\"type\\": \\"image_url\\", \\"image_url\\": {\\"url\\": \\"data:image/jpeg;base64,${FRAME3}\\"}},
    {\\"type\\": \\"image_url\\", \\"image_url\\": {\\"url\\": \\"data:image/jpeg;base64,${FRAME4}\\"}},
    {\\"type\\": \\"image_url\\", \\"image_url\\": {\\"url\\": \\"data:image/jpeg;base64,${FRAME5}\\"}},
    {
    \\"type\\": \\"text\\",
    \\"text\\": \\"以上是一段视频的连续帧,请描述视频的内容、场景和发生了什么事情。\\"
    }
    ]
    }
    ],
    \\"max_tokens\\": 1024
    }"

    6.python示例

    from openai import OpenAI
    import base64

    client = OpenAI(
    base_url="http://192.168.0.254:8005/v1",
    api_key="dummy" # vLLM 本地不需要真实 key
    )

    # —- 1. 健康检查 —-
    models = client.models.list()
    print("可用模型:", [m.id for m in models.data])

    # —- 2. Chat —-
    response = client.chat.completions.create(
    model="gemma-4-31b",
    messages=[{"role": "user", "content": "用一句话介绍你自己"}],
    max_tokens=256
    )
    print("Chat:", response.choices[0].message.content)

    # —- 3. 图片理解 —-
    with open("荷花.png", "rb") as f:
    img_b64 = base64.b64encode(f.read()).decode()

    response = client.chat.completions.create(
    model="gemma-4-31b",
    messages=[{
    "role": "user",
    "content": [
    {"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{img_b64}"}},
    {"type": "text", "text": "详细描述这张图片"}
    ]
    }],
    max_tokens=512
    )
    print("图片理解:", response.choices[0].message.content)

    # —- 4. 视频理解(多帧) —-
    import shutil
    import subprocess
    import tempfile
    from pathlib import Path

    # Windows 上 WinError 2:通常是未安装 ffmpeg 或未加入 PATH(需能直接运行 ffmpeg.exe)
    _ffmpeg = shutil.which("ffmpeg")
    if not _ffmpeg:
    raise SystemExit(
    "未找到 ffmpeg:请安装并加入 PATH,例如:\\n"
    " winget install Gyan.FFmpeg\\n"
    "或从 https://ffmpeg.org/download.html 下载,把 bin 目录加到系统 PATH。"
    )

    _video = Path("12345.mp4")
    if not _video.is_file():
    raise SystemExit(f"找不到视频文件: {_video.resolve()},请把 12345.mp4 放在当前工作目录或改成正确路径。")

    # 抽帧(不要用 /tmp/,Windows 下一般不存在)
    _tmp = Path(tempfile.mkdtemp(prefix="vframes_"))
    subprocess.run(
    [
    _ffmpeg,
    "-i",
    str(_video),
    "-vf",
    "fps=1",
    "-frames:v",
    "5",
    str(_tmp / "frame%d.jpg"),
    "-y",
    ],
    check=True,
    )

    frames = []
    for i in range(1, 6):
    with open(_tmp / f"frame{i}.jpg", "rb") as f:
    b64 = base64.b64encode(f.read()).decode()
    frames.append({
    "type": "image_url",
    "image_url": {"url": f"data:image/jpeg;base64,{b64}"}
    })

    frames.append({
    "type": "text",
    "text": "以上是视频的连续帧,请描述视频内容和发生的事情。"
    })

    response = client.chat.completions.create(
    model="gemma-4-31b",
    messages=[{"role": "user", "content": frames}],
    max_tokens=1024
    )
    print("视频理解:", response.choices[0].message.content)

    赞(0)
    未经允许不得转载:171主机测评 » 在DGX-Spark上多模态模型gemma-4-31B-it vLLM部署
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址