基于 OpenGlass 的多模型图像描述基准测试:用提示词序列验证 moondream、llava 与多模态能力对比

原创2026-10-02 20:57:47987 阅读
文章标签:人工智能AI 应用智能硬件本地部署可穿戴AI Agent

基于 OpenGlass 的多模型图像描述基准测试:用提示词序列验证 moondream、llava 与多模态能力对比

在 OpenGlass(开源智能眼镜)项目中,prompts/series_1 目录下存放了一组以编号(img_1 ~ img_57)组织的图像与对应的 .md 描述文件,img_5.md 正是这套图像描述评测体系中的一份输出记录。该文件记录了同一张图片(一位浅金色卷发、穿深色短袖上衣的年轻男子,在带有工业风格玻璃天窗屋顶的室内空间中低头专注操作手机)经过 4 个不同多模态模型推理后的完整描述文本。本文以这份记录为核心,结合 prompts/generate.ts、sources/agent/imageDescription.ts 以及 sources/modules/ollama.ts 等源码,讲清楚这套基准测试的运行机制、模型差异、输出格式,以及如何把图像描述能力接入 OpenGlass 的应用链路。读完后,你将掌握 OpenGlass 中图像描述评测管线的完整原理,能读懂、复现乃至扩展这套多模型对比实验。

一、img_5.md 是什么:一份多模型图像描述评测样本

img_5.md 的文本结构非常清晰:文件由 4 个以 #### 包裹的小节组成,每个小节对应一个模型对 img_5.jpeg(600x800)这张图片的描述输出:

####Description####
In the image, a man is standing in an indoor space and looking at his cell phone. ...

####Description (llava-llama3)####
In the center of a bustling train station, a man in a blue shirt is engrossed in his phone. ...

####Description (llava:34b-v1.6)####
The image shows an indoor setting with a high ceiling, suggesting it might be a large hall or station. ...

####Description (moondream:1.8b-v2-fp16)####
The image features a young man standing in an indoor space, surrounded by other people. ...

四个小节对应的模型分别是:

小节标题 实际模型标识 备注
####Description#### moondream:1.8b-v2-fp16(默认模型) 与最后一个小节实际是同一模型
####Description (llava-llama3)#### llava-llama3 Ollama 生态的 LLaVA 变体
####Description (llava:34b-v1.6)#### llava:34b-v1.6 34B 参数规模的 LLaVA 1.6
####Description (moondream:1.8b-v2-fp16)#### moondream:1.8b-v2-fp16 fp16 量化版 1.8B 视觉语言模型

需要特别说明的是:####Description####(无后缀)与 ####Description (moondream:1.8b-v2-fp16)#### 来自同一个模型。这一点可以从 prompts/generate.ts 的调用逻辑确认:runTest('Description', ...) 调用 imageDescription(img) 时未显式传模型参数,而 sources/agent/imageDescription.ts 中该参数默认值为 'moondream:1.8b-v2-fp16',因此第一小节实质是 moondream 的第二次独立采样。这也解释了为什么两份描述在措辞上各有侧重——大语言模型采样存在随机性,同一提示词两次生成结果会略有差异,这是评测中值得关注的方差来源。

二、评测管线如何生成 img_5.md:generate.ts 的执行流程

这些 .md 文件并非手工编写,而是由 prompts/generate.ts 这个 TypeScript 脚本批量生成。其完整执行流程如下:

  1. 扫描图片目录:脚本读取 prompts 下所有子目录(如 series_1),遍历其中所有 .jpeg 后缀文件,将每张图片与对应的 .md 输出路径(把 .jpeg 替换为 .md)组成测试项。
  2. 逐模型批量推理:对每一批图片依次执行 4 次 runTest,分别调用:
    • imageDescription(img)——默认 moondream 模型;
    • imageDescription(img, 'llava-llama3');
    • imageDescription(img, 'llava:34b-v1.6');
    • imageDescription(img, 'moondream:1.8b-v2-fp16')。
  3. 追加写入输出:每个模型的输出都会以 '####' + title + '####\n' + 输出文本 + '\n' 的格式追加到该图片对应的 .md 文件中,最终形成 img_5.md 这样的小节化记录。

值得注意的两点实现细节:

  • 脚本同时导入了 sources/agent/imageBlurry.ts,但图像模糊度检测的调用被注释掉(// console.log(\Run blurry tests`)`),说明当前版本仅启用描述评测,模糊检测属于预留能力。
  • 脚本使用 cli-progress 库在终端显示进度条,适合一次跑 57 张图片、4 个模型的长时间批量任务。

三、核心 API:imageDescription 的调用链与提示词设计

sources/agent/imageDescription.ts 是整个评测的核心封装,其函数签名与实现如下:

export async function imageDescription(src: Uint8Array, model: KnownModel = 'moondream:1.8b-v2-fp16'): Promise<string> {
    return ollamaInference({
        model: model,
        messages: [{
            role: 'system',
            content: 'You are a very advanced model and your task is to describe the image as precisely as possible. Transcribe any text you see.'
        }, {
            role: 'user',
            content: 'Describe the scene',
            images: [src],
        }]
    });
}

这里有两个关键设计:

  • System Prompt 要求“尽可能精确地描述图像,并转写画面中可见的任何文字”。这解释了 img_5.md 中 llava:34b-v1.6 输出那句“There is no visible text in the image to transcribe.”——模型忠实执行了“转写文字”的指令,同时如实报告画面中不存在可见文本。这也是 README.md 中“translate text(翻译文本)”能力在评测层的体现。
  • User Prompt 固定为 'Describe the scene',保证 4 个模型在同一指令下可比,这是形成公平基准的前提。

该函数最终将请求交给 sources/modules/ollama.ts 中的 ollamaInference。它不依赖官方 Ollama SDK,而是直接用 axios 向 Ollama 的 /api/chat 端点发起 POST 请求:

let resp = await axios.post(keys.ollama, {
    stream: false,
    model: args.model,
    messages: converted,
});
return trimIdent(((response.message?.content ?? '') as string));

其中 stream: false 表示等待完整响应而非流式输出;keys.ollama 即 Ollama 服务的地址(来自 sources/keys.ts,对应环境变量 EXPO_PUBLIC_OLLAMA_API_URL,默认 http://localhost:11434/api/chat)。

图片如何送入模型:Uint8Array → Base64

多模态模型无法直接接收二进制流,ollamaInference 内部先对每条消息中的 images 字段做 Base64 编码转换:

images: message.images ? message.images.map((image) => toBase64(image)) : undefined,

toBase64 实现在 sources/utils/base64.ts:把 Uint8Array 逐字节转成字符后调用 btoa。因此 generate.ts 中 fs.readFileSync 读出的图片 Buffer,最终会以 Base64 字符串的形式进入 Ollama 的请求体。整个调用链可概括为:

generate.ts 读取 .jpeg
→ imageDescription(img, model) 组装 system + user 消息
→ ollamaInference() 将图片转为 Base64
→ axios POST {stream:false, model, messages} 到 keys.ollama
→ 返回 response.message.content 并 trimIdent 清洗
→ 追加写入对应 .md 文件

四、模型输出差异分析:从 img_5.md 看到的多模态能力对比

对照 prompts/series_1/img_5.jpeg 的真实内容(浅金色卷发、深色短袖上衣的年轻男子,站在带玻璃天窗的工业风室内空间低头看手机,背景有其他人、金属桁架、管线等),四份描述呈现明显的分层:

维度 moondream(两份) llava-llama3 llava:34b-v1.6
场景判定 “indoor space / 室内空间”,无具体化 具体化为“bustling train station(繁忙火车站)” 谨慎表述为“large hall or station(大厅或车站)”
人物细节 描述为“young man”,只提到看手机 描述为“man in a blue shirt”,补充“把手机举到脸前” 补充“浅色头发、休闲T恤、把手机举到面前端详”
环境细节 仅“有其他人” 展开天花板金属工艺、光影、铁轨、现代生活叙事 展开高天花板、自然光、管道与柱子、工业美学
幻觉风险 低,忠于事实 中,自行脑补“train station + 铁轨”细节 中低,用“suggests / might be”保持不确定性

这份样本直观展示了不同参数规模与训练数据的视觉语言模型在场景具体化程度、细节丰富度、以及幻觉倾向上的差异:

  • moondream(1.8B)输出最保守、最短,聚焦核心事实(人在室内看手机),可靠性高但信息量低;
  • llava-llama3 叙事感最强,甚至虚构出“铁轨通向远方”等画面中未必存在的元素,说明小参数 LLaVA 变体更容易脑补;
  • llava:34b-v1.6 在信息量与严谨性之间最平衡:既给出丰富细节,又用“suggesting / might be”的措辞避免过度断言,并如实报告“画面中没有可见文字”。

这正是 OpenGlass 保留多模型评测的意义:为“识人、识物、读场景”等实时功能选择模型时,需要在细节丰富度与事实准确度之间做权衡,而 prompts/series_1 下 57 张样本的批量对比记录,为这种选型决策提供了可复现的依据。

五、把图像描述接入真实应用:Agent 层的完整链路

这套评测所用的 imageDescription 并不只服务于离线的 .md 生成,它与 OpenGlass 的运行时 Agent 共享同一套底层能力。sources/agent/imageDescription.ts 还导出了另外两个问答函数:

  • llamaFind(question, images):把多份图像描述文本拼进 system prompt,交给 Groq 上的 llama3-70b-8192 回答问题(实现在 sources/modules/groq-llama3.ts,请求 https://api.groq.com/openai/v1/chat/completions,鉴权头 Authorization: Bearer ${keys.groq});
  • openAIFind(question, images):同样模式,但改调 OpenAI 的 gpt-4o(实现在 sources/modules/openai.ts 的 gptRequest)。

两个问答函数的 system prompt 完全一致,核心约束是:

You are a smart AI that need to read through description of a images and answer user's questions.
DO NOT mention the images, scenes or descriptions in your answer, just answer the question.
DO NOT try to generalize or provide possible scenarios.
ONLY use the information in the description of the images to answer the question.
BE concise and specific.

这揭示了 OpenGlass 的典型“感知-推理”两段式架构:第一段用本地 Ollama 多模态模型把图像转成文字描述(如 img_5.md 中的记录),第二段把描述作为上下文交给更强的文本 LLM(Groq 的 llama3-70b 或 OpenAI 的 gpt-4o)来回答“画面里的人在哪儿、在做什么”这类问题。评测中积累的 .md 描述恰好可以作为第二段的输入样例,甚至能直接复用 prompts/generate.ts 的模式扩展出“描述→问答”的端到端评测。

六、如何复现这套评测:从拉取模型到运行 generate.ts

如果你希望在自己的环境复现 img_5.md 的生成过程,可按以下步骤操作(以当前仓库为准):

  1. 确认依赖:仓库根目录执行 npm install(或 yarn install)。本项目是 Expo 项目,运行前需按 README.md 配置环境变量,在 sources/keys.ts 对应的环境变量中填入密钥与 Ollama 地址:
    • EXPO_PUBLIC_GROQ_API_KEY:Groq API Key;
    • EXPO_PUBLIC_OPENAI_API_KEY:OpenAI API Key;
    • EXPO_PUBLIC_OLLAMA_API_URL:Ollama 服务地址,默认 http://localhost:11434/api/chat。 (提示:imageDescription 链路只依赖 Ollama,不跑问答阶段时 Groq/OpenAI 密钥可留空。)
  2. 启动 Ollama 并拉取模型:本地启动 Ollama 服务后,执行 ollama pull moondream:1.8b-v2-fp16,并按需拉取 llava-llama3、llava:34b-v1.6。sources/modules/ollama.ts 中 KnownModel 类型列出了本仓库支持的完整模型名单:llama3、llama3-gradient、llama3:8b-instruct-fp16、llava-llama3、llava:34b-v1.6、moondream:1.8b-v2-fp16、moondream:1.8b-v2-moondream2-text-model-f16。
  3. 运行评测脚本:在 prompts 目录执行 TypeScript 运行脚本(如 npx ts-node prompts/generate.ts),脚本会扫描所有 series_* 目录下的 .jpeg,逐个模型批量生成描述并覆写对应 .md 文件。

注意:仓库是只读的,以上操作描述的是在你本地克隆副本中的复现方式;且本项目为 Expo 应用,评测脚本属于开发工具链的一部分,需 Node.js 环境(含 ts-node 或等价 TypeScript 执行器)支持。

七、扩展思路:从 img_5.md 出发还能做什么

基于现有实现,可以在不改动仓库的前提下做进一步实验:

  1. 加入新模型:在 KnownModel 允许的模型名范围内,在 prompts/generate.ts 中新增一个 runTest 调用,即可横向对比更多视觉语言模型(当前仓库的类型定义已预留了 moondream:1.8b-v2-moondream2-text-model-f16 等多个选项)。
  2. 对比稳定性:####Description#### 与 ####Description (moondream:1.8b-v2-fp16)#### 两份输出证明同一模型多次采样存在措辞漂移,可据此统计描述质量方差,评估哪个模型更适合作为 OpenGlass 的默认视觉后端。
  3. 启用模糊检测:取消 prompts/generate.ts 中对 imageBlurry 的注释,可将“画面模糊度”指标纳入样本记录,帮助筛选适合在眼镜端实时拍摄的低光照/运动模糊场景。
  4. 端到端问答评测:把 imageDescription 的输出直接喂给 llamaFind / openAIFind,验证“感知→推理”链路在真实图片上的回答质量。

结语

img_5.md 看似只是几段模型描述文本,实则是 OpenGlass 多模态评测体系的一个最小样本:它由 prompts/generate.ts 自动化生成,经由 sources/agent/imageDescription.ts → sources/modules/ollama.ts 的调用链完成推理,记录了 4 份可复现、可对比的模型输出。无论是研究多模态模型差异、为智能眼镜选型视觉模型,还是扩展“描述→问答”的 Agent 能力,这份样本及其背后的管线都是极佳的起点。

登录后查看全文
OpenGlass