1. 一句话定位:三者根本不是一个层级

工具 本质定位 你应该怎么理解
vLLM 高性能 LLM/VLM 推理引擎 + OpenAI API Server 生产级推理服务,核心是吞吐、并发、KV Cache 管理
SGLang 高性能推理运行时 + 结构化生成编程框架 更适合复杂 Agent / RAG / JSON / 多轮 / 重复前缀任务
Ollama 本地模型运行器 + 模型管理工具 最适合个人电脑、本地 demo、低门槛体验,不是高并发生产推理引擎

如果要做公司级医疗 VLM 服务,用 Ollama 当核心推理后端是不专业的;如果只是本地跑 Qwen2.5-VL 看图、做 demo,用 vLLM/SGLang 又可能是过度工程。


2. 原理层面的核心区别

2.1 vLLM:核心是 “高吞吐推理引擎” 🚀

vLLM 的核心技术是 PagedAttention。它把 KV Cache 管理做得像操作系统的虚拟内存分页:每个请求的 KV Cache 不需要连续存放,而是通过 block/page table 映射到 GPU 显存中的不同块,从而减少显存碎片,提高 batch 容量。vLLM 论文里明确说它的目标是解决 KV Cache 动态增长导致的显存浪费,并在实验中相比当时系统获得 2–4 倍吞吐提升。([arXiv][1])

vLLM 还有 continuous batching:不是等一个 batch 里的所有请求都结束再处理下一批,而是每个 decode step 动态把新请求插进来,提升 GPU 利用率。Qwen 官方部署文档也推荐用 vLLM 跑 Qwen,因为它支持 PagedAttention、continuous batching、优化 CUDA kernel 和 OpenAI-compatible API。([Qwen][2])

可以把 vLLM 理解成:

用户请求
  ↓
OpenAI-compatible API Server
  ↓
Tokenizer / Multimodal Processor
  ↓
Scheduler 连续调度
  ↓
KV Cache Block Manager / PagedAttention
  ↓
GPU Worker / CUDA Kernel
  ↓
Sampling
  ↓
流式返回 token

它最关心的是:

  • GPU 利用率
  • 高并发吞吐
  • TTFT / ITL
  • KV Cache 显存占用
  • Tensor Parallel / 多卡部署
  • OpenAI API 兼容

2.2 SGLang:核心是 “结构化生成 + Prefix Cache 复用” 🧠

SGLang 不只是推理 server,它最早的定位是 structured language model programs。它由两部分组成:

  1. Frontend language:让你写多步生成、分支、并行、结构化输出。
  2. Runtime:负责高性能执行,核心优化包括 RadixAttention、prefix caching、structured output decoding、continuous batching 等。SGLang 论文明确说它用 RadixAttention 复用 KV Cache,并用 compressed finite state machine 加速结构化输出解码。([arXiv][3])

SGLang 官方文档也强调它是面向 LLM 和 VLM 的高性能 serving framework,支持 RadixAttention、prefix caching、多 GPU、OpenAI-compatible API,并支持 Llama、Qwen、DeepSeek 等模型。([SGLang Documentation][4])

可以把 SGLang 理解成:

复杂任务程序 / OpenAI 请求
  ↓
Prompt / Tool Schema / Few-shot / Image 输入
  ↓
Radix Tree 查找共享前缀
  ↓
复用已经计算过的 KV Cache
  ↓
Scheduler + Runtime 执行
  ↓
结构化约束解码 / JSON / 多轮生成
  ↓
返回结果

它最强的地方不是“单次聊天快一点”,而是:

  • 大量请求共享系统 prompt
  • RAG 每次都有相似模板
  • Agent 每次都有相同 tool schema
  • JSON / function calling / constrained decoding
  • 多轮、多分支、多次 LLM call 的复杂任务

这点对医疗 Agent 很关键。
你的医疗 Agent 里如果每次都带一大段系统规则、疾病分类、工具 schema、输出 JSON 格式,SGLang 的 prefix cache / RadixAttention 就很有价值。


2.3 Ollama:核心是 “本地模型运行体验” 🧩

Ollama 的定位完全不同。它不是优先追求极限吞吐,而是让你用很低门槛在本地跑模型:

ollama run qwen2.5vl

它有 CLI、REST API、Python/JS SDK、模型库、Modelfile。Ollama 官方文档说它的 API 默认跑在 http://localhost:11434/api,可用 REST 方式访问;GitHub README 也展示了 /api/chat、Python SDK 和 JavaScript SDK。([docs.ollama.com][5])

Ollama GitHub README 还列出其 supported backend 包括 llama.cpp,并且项目主要语言是 Go/C/C++。这说明 Ollama 更像是把本地模型下载、管理、运行、API 暴露包装起来,而不是像 vLLM/SGLang 那样专门为大规模 GPU server serving 设计。([GitHub][6])

Ollama 的 Modelfile 类似一个本地模型蓝图,可以定义 base model、参数、prompt template、system message、adapter、license、message history 等。([docs.ollama.com][7])

可以把 Ollama 理解成:

ollama run / REST API
  ↓
模型管理 / Modelfile / 本地模型库
  ↓
Runner 后端
  ↓
llama.cpp 等本地推理后端
  ↓
本机 CPU / GPU / Metal / CUDA
  ↓
本地返回

它适合:

  • Mac / Windows / Linux 本地试模型
  • 个人 RAG demo
  • OpenWebUI / AnythingLLM / Dify 本地接入
  • 本地隐私场景
  • 快速体验 Qwen、Llama、Gemma、DeepSeek 等

它不适合:

  • 高 QPS
  • 多租户生产服务
  • 精细 GPU 调度
  • 多卡大模型服务
  • 严格 SLA 的企业在线推理

3. 代码层面的差异

3.1 vLLM 代码使用方式

启动 Qwen2.5-VL

pip install vllm

vllm serve Qwen/Qwen2.5-VL-7B-Instruct \
  --host 0.0.0.0 \
  --port 8000 \
  --gpu-memory-utilization 0.90 \
  --limit-mm-per-prompt '{"image": 4}'

vLLM 官方多模态文档显示,vLLM 支持 Qwen2.5-VL,并且 OpenAI-compatible server 可以通过 Chat Completions API 接收多模态输入。([docs.vllm.ai][8])

Python 客户端调用

from openai import OpenAI
import base64
from pathlib import Path

client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="EMPTY",
)

img_b64 = base64.b64encode(Path("ct_report.jpg").read_bytes()).decode()

resp = client.chat.completions.create(
    model="Qwen/Qwen2.5-VL-7B-Instruct",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "text",
                    "text": "请分析这张医疗报告图片,提取关键字段,并输出 JSON。"
                },
                {
                    "type": "image_url",
                    "image_url": {
                        "url": f"data:image/jpeg;base64,{img_b64}"
                    }
                }
            ]
        }
    ],
    temperature=0.1,
    max_tokens=1024,
)

print(resp.choices[0].message.content)

vLLM 适合的代码工程结构

FastAPI / Gateway
  ↓
OpenAI-compatible client
  ↓
vLLM Server
  ↓
Prometheus / Grafana
  ↓
GPU Metrics / KV Cache Metrics

你的医疗 VLM 项目如果是:

  • 前端上传报告图片
  • OCR + VLM 分析
  • 多用户并发问答
  • 内网服务部署
  • H20 / A100 / H100 等 GPU

vLLM 是默认优先选项


3.2 SGLang 代码使用方式

启动 Qwen2.5-VL

pip install "sglang[all]"

python -m sglang.launch_server \
  --model-path Qwen/Qwen2.5-VL-7B-Instruct \
  --host 0.0.0.0 \
  --port 30000

SGLang 文档中也给过 Qwen/Qwen2.5-VL-7B-Instruct 的 launch server 示例,并支持 OpenAI-compatible endpoint。([SGLang Documentation][9])

OpenAI-compatible 调用

from openai import OpenAI
import base64
from pathlib import Path

client = OpenAI(
    base_url="http://localhost:30000/v1",
    api_key="EMPTY",
)

img_b64 = base64.b64encode(Path("invoice.png").read_bytes()).decode()

resp = client.chat.completions.create(
    model="Qwen/Qwen2.5-VL-7B-Instruct",
    messages=[
        {
            "role": "system",
            "content": "你是一个严格的文档结构化抽取助手,只输出 JSON。"
        },
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "提取发票中的公司名、金额、日期、税号。"},
                {
                    "type": "image_url",
                    "image_url": {
                        "url": f"data:image/png;base64,{img_b64}"
                    }
                }
            ]
        }
    ],
    temperature=0.0,
    max_tokens=1024,
)

print(resp.choices[0].message.content)

SGLang 更特别的地方:写“生成程序”

这类代码风格才是 SGLang 和 vLLM 的真正区别:

import sglang as sgl

@sgl.function
def medical_triage(s, image_path, question):
    s += sgl.system(
        "你是急诊预检分诊助手。你必须先判断风险等级,再给出结构化 JSON。"
    )

    s += sgl.user(
        sgl.image(image_path)
        + f"""
请根据图片和问题完成分析:

问题:{question}

输出 JSON:
{{
  "risk_level": "...",
  "key_findings": [],
  "recommended_department": "...",
  "need_emergency": true/false
}}
"""
    )

    s += sgl.assistant(sgl.gen("answer", max_tokens=1024, temperature=0.0))

result = medical_triage.run(
    image_path="report.jpg",
    question="这个报告是否需要尽快去急诊?"
)

print(result["answer"])

这类任务里,很多请求共享:

系统角色
输出 JSON schema
医疗安全规则
疾病分类规则
工具说明

SGLang 的 RadixAttention / prefix caching 对这种场景更友好。vLLM 也有 prefix caching,但 SGLang 的设计起点更偏 复杂生成程序和结构化任务


3.3 Ollama 代码使用方式

本地跑 Qwen2.5-VL

ollama run qwen2.5vl

Ollama 模型库已经提供 Qwen2.5-VL,页面说明该模型可理解文本、图表、布局,也支持视觉定位和结构化输出;该页面还注明此模型要求 Ollama 0.7.0 以上。([ollama.com][10])

命令行图片输入

ollama run qwen2.5vl ./report.jpg "请分析这张报告图片,并提取关键信息。"

Ollama Vision 文档说明 vision models 可以同时接收图片和文本,CLI 可以直接传图片路径,REST API 则需要 base64 图像数据。([docs.ollama.com][11])

REST API 调用

IMG=$(base64 < report.jpg | tr -d '\n')

curl -X POST http://localhost:11434/api/chat \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen2.5vl",
    "messages": [
      {
        "role": "user",
        "content": "请分析这张医疗报告图片,输出关键结论。",
        "images": ["'"$IMG"'"]
      }
    ],
    "stream": false
  }'

Ollama 的 /api/chat endpoint 接收 modelmessagestoolsformatoptionsstream 等字段,并返回响应内容、耗时、prompt token 统计和生成 token 统计。([docs.ollama.com][12])

Python 调用

from ollama import chat

response = chat(
    model="qwen2.5vl",
    messages=[
        {
            "role": "user",
            "content": "这张图里有什么?请用中文简洁回答。",
            "images": ["report.jpg"],
        }
    ],
)

print(response.message.content)

Ollama 最爽的地方就是这个:部署成本极低。但别误判它的定位。它是非常好的本地入口,不是你公司医疗 VLM 高并发服务的最优底座。


4. 应用场景对比

场景 推荐
本地快速体验 Qwen2.5-VL Ollama
写一个本地 OCR/VQA demo Ollama / vLLM
企业内部多用户 VLM 服务 vLLM
高并发在线聊天服务 vLLM
医疗报告结构化抽取 API vLLM / SGLang
多轮 Agent + 工具调用 + 复杂 JSON SGLang
RAG 中大量重复 system prompt / tool schema SGLang
多卡部署 32B / 72B vLLM / SGLang
个人电脑、Windows、Mac 快速跑模型 Ollama
教学、演示、低门槛产品原型 Ollama

5. 用 Qwen2.5-VL 举一个完整案例

案例:医疗报告图片分析系统

假设你要做一个功能:

用户上传体检报告 / CT 报告 / 检验单图片,系统自动识别关键信息,输出结构化 JSON,并给出初步风险提示。

Qwen2.5-VL 很适合这个例子,因为它技术报告里强调了文档理解、表格/表单抽取、图表/布局分析、bounding box/point 定位、动态分辨率和视觉 Agent 能力。([arXiv][13])


方案 A:Ollama 本地 demo 版

适合你做什么?

  • 自己电脑测试
  • 写公众号演示
  • 给同事展示“本地 VLM 能看图”
  • 不追求高并发

架构

Local UI / Python Script
  ↓
Ollama API
  ↓
qwen2.5vl
  ↓
返回分析结果

代码

from ollama import chat

resp = chat(
    model="qwen2.5vl",
    messages=[
        {
            "role": "user",
            "content": """
请读取这张检验报告图片,提取:
1. 检查项目
2. 异常指标
3. 可能风险
4. 建议就诊科室

只输出 JSON。
""",
            "images": ["lab_report.jpg"],
        }
    ],
)

print(resp.message.content)

评价

优点:

  • 安装简单
  • 上手快
  • 适合本地隐私测试
  • 不需要复杂 CUDA 环境

缺点:

  • 并发能力弱
  • 多卡能力弱
  • 监控、调度、吞吐优化弱
  • 不适合正式生产医疗服务

方案 B:vLLM 生产 API 版

适合你做什么?

  • 医院内网部署
  • 多用户上传报告
  • WebSocket / FastAPI 服务
  • GPU server 常驻
  • 追求吞吐和稳定性

架构

Web 前端
  ↓
FastAPI Gateway
  ↓
图片预处理 / 安全检查
  ↓
vLLM OpenAI-compatible Server
  ↓
Qwen2.5-VL-7B / 32B / 72B
  ↓
结构化结果
  ↓
数据库 / 前端展示

启动

vllm serve Qwen/Qwen2.5-VL-7B-Instruct \
  --host 0.0.0.0 \
  --port 8000 \
  --gpu-memory-utilization 0.90 \
  --max-model-len 32768 \
  --limit-mm-per-prompt '{"image": 4}'

FastAPI 简化版

from fastapi import FastAPI, UploadFile
from openai import OpenAI
import base64

app = FastAPI()

client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="EMPTY",
)

@app.post("/analyze-report")
async def analyze_report(file: UploadFile):
    image_bytes = await file.read()
    image_b64 = base64.b64encode(image_bytes).decode()

    resp = client.chat.completions.create(
        model="Qwen/Qwen2.5-VL-7B-Instruct",
        messages=[
            {
                "role": "system",
                "content": "你是医疗报告结构化抽取助手。不要做最终诊断,只做信息抽取和风险提示。"
            },
            {
                "role": "user",
                "content": [
                    {
                        "type": "text",
                        "text": """
请从报告图片中提取:
- patient_info
- exam_items
- abnormal_findings
- risk_level
- suggested_department

输出严格 JSON。
"""
                    },
                    {
                        "type": "image_url",
                        "image_url": {
                            "url": f"data:image/jpeg;base64,{image_b64}"
                        }
                    }
                ]
            }
        ],
        temperature=0.0,
        max_tokens=1500,
    )

    return {"result": resp.choices[0].message.content}

评价

优点:

  • 高吞吐
  • OpenAI API 兼容
  • 多卡部署成熟
  • 适合服务化
  • 更容易接 Prometheus/Grafana/网关

缺点:

  • 安装环境复杂
  • 对 CUDA / Torch / 驱动版本敏感
  • VLM 显存压力比纯文本大
  • 复杂 Agent workflow 不是它的核心抽象

方案 C:SGLang Agent / 结构化任务版

适合你做什么?

  • 医疗 Agent
  • 分诊流程
  • 多轮问诊
  • 工具调用
  • JSON 输出
  • 反复复用系统 prompt / tool schema

架构

用户问题 + 图片
  ↓
医疗 Agent Planner
  ↓
SGLang Program
  ↓
Qwen2.5-VL
  ↓
结构化 JSON
  ↓
风险规则校验
  ↓
最终回答

示例

import sglang as sgl

@sgl.function
def triage_vlm(s, image_path, user_question):
    s += sgl.system("""
你是急诊预检分诊助手。
规则:
1. 不能给出最终诊断。
2. 必须判断是否存在急症风险。
3. 必须输出 JSON。
4. 如果信息不足,必须指出缺失信息。
""")

    s += sgl.user(
        sgl.image(image_path)
        + f"""
用户问题:
{user_question}

请输出:
{{
  "emergency_risk": "low/medium/high",
  "evidence_from_image": [],
  "missing_information": [],
  "recommended_action": "",
  "department": ""
}}
"""
    )

    s += sgl.assistant(
        sgl.gen("answer", max_tokens=1200, temperature=0.0)
    )

result = triage_vlm.run(
    image_path="report.jpg",
    user_question="这个报告是不是需要马上去医院?"
)

print(result["answer"])

评价

优点:

  • 适合复杂 Agent 流程
  • 适合结构化输出
  • 适合多轮、多分支、多次生成
  • prefix cache 对固定医疗规则 / tool schema 很有价值

缺点:

  • 学习曲线比 Ollama 高
  • 工程生态不如 vLLM 普及
  • 如果只是单次 chat completion,它的优势不一定明显

6. 关键选型结论

应该这样选

目标 直接选
学习、本地试玩 Qwen2.5-VL Ollama
给公众号/同事演示 VLM 看图 Ollama
公司内部部署 Qwen2.5-VL API vLLM
医疗 VLM 服务,多用户并发 vLLM
医疗 Agent,有固定流程、JSON、工具 schema SGLang
RAG/Agent 请求大量共享长 prompt SGLang
140GB H20 上跑 32B/72B 服务 vLLM 或 SGLang
想做真正推理服务工程能力 先 vLLM,再 SGLang

7. 最该建立的技术判断

很多人会犯一个幼稚错误:
“我本地 Ollama 能跑,所以我公司服务也用 Ollama。”

这就是把 demo runner 当成 production inference engine。错误。

要建立的是这个分层:

应用层:
  医疗 Agent / RAG / OCR / 前端 / 业务 API

编排层:
  LangGraph / 自研 Agent Loop / SGLang Program

推理服务层:
  vLLM / SGLang

本地体验层:
  Ollama / LM Studio / llama.cpp

模型层:
  Qwen2.5-VL / Qwen3-VL / Llama / DeepSeek / Gemma

更狠一点说:

  • Ollama 帮你快速开始。
  • vLLM 帮你把模型服务化。
  • SGLang 帮你把复杂生成任务工程化。

你如果目标是“面试 + 工程能力 + 医疗多模态 Agent”,学习优先级应该是:

1. vLLM:必须掌握
2. SGLang:进阶掌握
3. Ollama:会用即可,不要投入太多底层时间

8. 最后给你一个具体落地路线 🧭

第一步:Ollama 跑通 Qwen2.5-VL

ollama run qwen2.5vl ./report.jpg "请分析这张图片"

目标:验证模型能力,不要纠结性能。


第二步:vLLM 部署同一个模型

vllm serve Qwen/Qwen2.5-VL-7B-Instruct \
  --host 0.0.0.0 \
  --port 8000 \
  --gpu-memory-utilization 0.90 \
  --limit-mm-per-prompt '{"image": 4}'

目标:学会真正服务化,包括并发、显存、max model len、batch、KV Cache。


第三步:SGLang 做结构化医疗 Agent

重点不是“跑起来”,而是设计这种 prompt/program:

固定系统规则
+ 图片输入
+ 用户问题
+ 医疗安全约束
+ JSON schema
+ 风险等级
+ 缺失信息检查
+ 工具调用

目标:把 VLM 从“看图聊天”升级成“可控的业务组件”。


最终判断

vLLM 打底,SGLang 进阶,Ollama 辅助 demo。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐