SGLang 视觉语言模型评测实战:基于 LLaVA-Bench-in-the-Wild 的多模态基准测试全流程指南
【免费下载链接】sglangSGLang is a high-performance serving framework for large language models and multimodal models.项目地址: https://gitcode.com/GitHub_Trending/sg/sglang
LLaVA-Bench(LLaVA-Bench-in-the-Wild)是一套面向视觉语言模型(VLM)的开放式问答评测集,用 24 张真实世界图片配 60 道开放式问题,考察模型在闲聊对话(conv)、细节描述(detail)与复杂推理(complex)三类能力上的表现。本文以当前仓库中的 benchmark/llava_bench 评测套件为主线,完整演示从图片下载、SGLang 服务启动、本地模型与 OpenAI 模型对照评测,到与 LLaVA 官方代码、llama.cpp 等其他推理后端横向对比的完整流程,并深入解读 bench_sglang.py 的脚本实现原理,帮助你快速搭建一套可复现的 VLM 评测流水线。
评测套件总览
benchmark/llava_bench目录下包含一套完整的评测工具链:
| 文件 | 作用 |
|---|---|
| download_images.py | 从 HuggingFace 数据集下载 24 张评测图片到本地images/目录 |
| questions.jsonl | 60 道评测问题,每行一条 JSON 记录 |
| bench_sglang.py | 核心评测脚本,可对接 SGLang 服务或任意 OpenAI 兼容后端 |
| bench_hf_llava_bench.sh | 调用 LLaVA 官方仓库代码跑同一份评测,作为基准对照 |
| bench_sglang_mme.sh | 将同一脚本扩展到 MME 多模态评测集 |
| bench_hf_mme.sh | MME 评测集的 HF 官方实现对照脚本 |
| README.md | 官方操作说明(本文即围绕其展开) |
这套套件的核心思想是:用同一份问题集、同样的输入方式去驱动不同后端,从而公平比较 SGLang 与其他框架的视觉问答效果与性能。问题集默认指questions.jsonl,也可通过参数替换为 MME 等其他评测集。
第一步:下载评测图片与依赖
下载评测图片
评测图片来源于 HuggingFace 上的liuhaotian/llava-bench-in-the-wild数据集。在benchmark/llava_bench目录下直接运行:
python3 download_images.py该脚本的逻辑非常直接(见 download_images.py):先创建本地images/目录,然后以001.jpg到024.jpg共 24 张图片为目标,通过wget从数据集的resolve/main/images/路径逐一下载。运行结束后,目录下应出现images/001.jpg~images/024.jpg共 24 个文件。
安装依赖
pip3 install "sglang[all]" pip3 install "torch>=2.1.2" "transformers>=4.36" pillow第一行安装完整版 SGLang(含多模态推理所需的视觉编码器等全部依赖),第二行确保 PyTorch、Transformers 与 Pillow 版本满足 LLaVA 模型加载与图片预处理的要求。若只做评测而不需要其他后端,也可以按 SGLang 官方安装文档选择最小依赖安装方式,但本评测需要视觉模型支持,建议直接使用[all]完整选项。
第二步:评测问题集结构
questions.jsonl 每行是一条 JSON 记录,包含四个字段:
{"image": "001.jpg", "text": "What is the name of this famous sight in the photo?", "category": "conv", "question_id": 0}image:图片文件名,评测脚本会将其与--image-folder拼接成绝对路径;text:开放式问题文本;category:问题类别,共三类——conv(日常对话,如"这是什么水果?")、detail(细节描述,如"详细描述这张照片")、complex(复杂推理,如"讨论这幅画对艺术史的影响");question_id:全局唯一编号(0~59)。
整个数据集由 24 张图片 × 每图 2~3 个问题构成,覆盖自然景观、艺术品、网络梗图、美食、室内场景等多样化题材,旨在考察模型在"真实世界"而非人工合成数据上的泛化能力。
第三步:用 SGLang 启动视觉模型服务
启动服务
python3 -m sglang.launch_server \ --model-path liuhaotian/llava-v1.6-vicuna-7b \ --tokenizer-path llava-hf/llava-1.5-7b-hf \ --port 30000关键点说明:
--model-path指定 LLaVA 模型权重(HuggingFace 仓库名或本地路径均可),示例使用的是liuhaotian/llava-v1.6-vicuna-7b;--tokenizer-path单独指定分词器来源。这里之所以指定llava-hf/llava-1.5-7b-hf,是因为部分 LLaVA 权重仓库不附带与推理后端匹配的分词器配置,显式指定可避免加载失败;--port 30000与评测脚本默认端口一致,也可在评测时通过--port覆盖。
启动成功后,SGLang 会暴露一个兼容 OpenAI Chat Completions 格式的 HTTP 服务,这也是评测脚本能够以统一接口访问不同后端的前提。
运行 SGLang 评测
# 使用本地 SGLang 服务 python3 bench_sglang.py --num-questions 60 # 或改用 OpenAI 视觉模型 python3 bench_sglang.py --num-questions 60 --backend gpt-4-vision-preview第一条命令会读取questions.jsonl的前 60 条(即全部问题),逐条向http://127.0.0.1:30000发送带图片的视觉问答请求;第二条命令将后端切换为gpt-4-vision-preview,通过 OpenAI API 完成同一份评测,用于对比开源部署与云端商用模型的差距。
完整参数说明
bench_sglang.py 在main入口处注册了全部可调参数:
| 参数 | 默认值 | 说明 |
|---|---|---|
--question-file | questions.jsonl | 评测问题文件 |
--answer-file | answers.jsonl | 模型回答输出文件 |
--image-folder | ./images | 图片所在目录 |
--temperature | 0.0 | 采样温度,默认 0 保证结果可复现 |
--num-questions | None(全部) | 只评测前 N 条问题 |
--max-tokens | 768 | 单条回答最大生成 token 数 |
--parallel | 64 | 并发线程数(来自通用参数) |
--host/--port | 127.0.0.1/30000 | SGLang 服务地址 |
--backend | srt | 后端类型,srt或gpt-* |
--device | auto | 设备类型:auto/cuda/rocm/cpu |
--result-file | result.jsonl | 性能统计结果文件 |
其中--parallel、--host、--port、--backend、--device、--result-file等通用参数由add_common_sglang_args_and_parse统一注入,该函数定义于 python/sglang/test/test_utils.py。
第四步:脚本内部实现原理
请求构造:SGLang 前端函数
评测脚本的核心是一个用@sgl.function装饰的视觉问答函数(见 bench_sglang.py):
@sgl.function def image_qa(s, image_file, question): s += sgl.user(sgl.image(image_file) + question) s += sgl.assistant(sgl.gen("answer", max_tokens=args.max_tokens))sgl.image(image_file)将本地图片路径嵌入用户消息,SGLang 前端会自动完成图片加载与编码;sgl.gen("answer", ...)声明一个名为answer的生成位置,结果会写入状态对象的answer字段;- 脚本注释中还保留了直接传
PIL.Image对象的备选写法,说明sgl.image同时支持路径与图像对象两种输入。
数据读取与后端选择
主流程中,脚本先用read_jsonl读取问题文件并按--num-questions截取,随后把每条记录构造成{"image_file": 绝对路径, "question": 文本}的参数字典(见 bench_sglang.py)。read_jsonl与dump_state_text等工具函数来自 python/sglang/utils.py。
后端选择由select_sglang_backend完成(定义于 python/sglang/test/test_utils.py):
--backend以srt开头 → 构造RuntimeEndpoint,指向--host:--port的本地 SGLang 服务;--backend以gpt-开头 → 构造OpenAI后端,走 OpenAI 兼容 API;- 其他值抛出
ValueError。
执行方式与结果落盘
执行分为两种模式(见 bench_sglang.py):
--parallel 1:单线程串行遍历,逐条image_qa.run(...);- 否则调用
image_qa.run_batch(arguments, temperature=0, num_threads=args.parallel, progress_bar=True)并发批处理,temperature=0保证确定性输出。
结束后脚本会打印总耗时Latency,并将两部分结果落盘:
- 每个问题的回答写入
--answer-file(answers.jsonl),字段包括question_id、原始prompt、生成text、model_id与metadata,供后续人工或自动评分使用; - 性能统计(任务名、后端、GPU 数、延迟、请求数与并发度)追加写入
--result-file(result.jsonl),便于多轮实验汇总对比。
第五步:与其他后端横向对比
对照 LLaVA 官方代码
为了验证 SGLang 部署的推理质量没有退化,可以用 LLaVA 官方实现跑同一份评测作为基线:
git clone git@github.com:haotian-liu/LLaVA.git cd LLaVA git reset --hard 9a26bd1435b4ac42c282757f2c16d34226575e96 pip3 install -e . cd ~/sglang/benchmark/llava_bench CUDA_VISIBLE_DEVICES=0 bash bench_hf_llava_bench.sh其中git reset --hard 9a26bd1435b4ac42c282757f2c16d34226575e96将 LLaVA 仓库锁定到与评测配套的固定提交,保证复现性。对照脚本 bench_hf_llava_bench.sh 实际执行的是:
python -m llava.eval.model_vqa \ --model-path liuhaotian/llava-v1.5-7b \ --question-file ./questions.jsonl \ --image-folder ./images \ --answers-file ./answers_hf.jsonl \ --temperature 0 \ --conv-mode vicuna_v1它与 SGLang 版共享同一份questions.jsonl与images/,输出answers_hf.jsonl与 SGLang 的answers.jsonl格式对齐,可以直接用同一套评分脚本对比。
对照 llama.cpp(CPU/混合部署)
如果你关心非 GPU 场景或轻量部署路径,llama.cpp 也提供了 OpenAI 兼容的视觉服务:
# 安装带 CUDA 支持的 llama-cpp-python CMAKE_ARGS="-DLLAMA_CUBLAS=on" pip install llama-cpp-python pip install sse_starlette starlette_context pydantic_settings # 下载 GGUF 格式权重 mkdir -p ~/model_weights/llava-v1.5-7b/ wget https://huggingface.co/mys/ggml_llava-v1.5-7b/resolve/main/ggml-model-f16.gguf -O ~/model_weights/llava-v1.5-7b/ggml-model-f16.gguf wget https://huggingface.co/mys/ggml_llava-v1.5-7b/resolve/main/mmproj-model-f16.gguf -O ~/model_weights/llava-v1.5-7b/mmproj-model-f16.gguf启动服务并复用评测脚本:
python3 -m llama_cpp.server \ --model ~/model_weights/llava-v1.5-7b/ggml-model-f16.gguf \ --clip_model_path ~/model_weights/llava-v1.5-7b/mmproj-model-f16.gguf \ --chat_format llava-1-5 \ --port 23000 OPENAI_BASE_URL=http://localhost:23000/v1 \ python3 bench_sglang.py --backend gpt-4-vision-preview --num-q 1这里通过--backend gpt-4-vision-preview复用 OpenAI 后端协议,再借助OPENAI_BASE_URL环境变量把请求重定向到本地 llama.cpp 服务。注意 README 中该示例写作--num-q 1,实际对应脚本参数是--num-questions 1,用于快速冒烟验证。
扩展:用同一脚本跑 MME 评测集
除 LLaVA-Bench 外,套件还内置了 MME(Multimodal Multitask Understanding Evaluation)评测的接入脚本。以 bench_sglang_mme.sh 为例:
MME_FOLDER=./mme_pack python3 bench_sglang.py --num-questions 5000 \ --question-file $MME_FOLDER/llava_mme_bench_replace.jsonl \ --answer-file answer_mme.jsonl \ --image-folder $MME_FOLDER/MME_Benchmark_release_version \ --max-tokens 4要点:
- MME 是短答案评测,因此把
--max-tokens压到 4,避免冗长输出干扰评分; - 只需替换
--question-file、--image-folder与--answer-file,其余流程与 LLaVA-Bench 完全一致; - 对应的 HF 官方对照脚本 bench_hf_mme.sh 同样基于
llava.eval.model_vqa_loader实现,两者输出可对齐比较。
结果解读与注意事项
评测结束后,建议按以下方式组织结论:
- 质量对比:对同一份
questions.jsonl,分别用 SGLang、LLaVA 官方、llama.cpp(或云端 GPT-4V)生成answers*.jsonl,再按category分组(conv / detail / complex)统计回答质量差异——SGLang 侧的输出中model_id字段记录了所用模型,便于溯源; - 性能对比:读取追加写入
result.jsonl的latency、num_requests、parallel字段,横向比较不同后端的吞吐与延迟;注意不同硬件、并发度(--parallel)下结果不可直接类比; - 复现性:全程使用
--temperature 0与固定的模型 commit,确保结果可复现;若更换模型或数据集,务必同步更新 README 中的镜像下载与参数配置。
实际使用中还需注意:评测图片需先运行 download_images.py 下载;LLaVA 官方对照需锁定到指定 commit;llama.cpp 路径依赖外部 GGUF 权重,需确认网络可达。整套流程从数据准备到多后端对比形成闭环,是验证 SGLang 视觉语言推理能力(正确性 + 性能)的轻量级、可复现的基准方案。
【免费下载链接】sglangSGLang is a high-performance serving framework for large language models and multimodal models.项目地址: https://gitcode.com/GitHub_Trending/sg/sglang
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考