首页 时政热点 科技头条 智能AI 安全攻防 数码硬件 开发者生态 归档 标签 关于

一个类似于 Jev 的单一功能 LLM 包装器,包括视觉模型

2026-09-26 1 阅读 约10分钟阅读 allanrbo
分享:
字号:
跳到主 |跳到侧边栏 Allan 的博客 Allan Riordan Boll 的博客 2026 年 9 月 25 日星期五 LLM 的类似 Jev 的包装器,包括视觉模型 我对 Jev 以及围绕它出现的自托管项目很感兴趣,例如 OpenJev 和 SemIf 。阅读这些内容后,我发现了一个巧妙的技巧:阅读法学硕士的象征概率。显然,这对某些人来说是一个老把戏。参见例如OpenAI 的 logprobs 食谱 。但这对我来说是新的。我相信基本的想法是写一个这样的提示:状态:我的订单到达时损坏了,我想要退款。问题:哪个团队应该处理这个问题? [A] 计费 [B] 运输 [C] 仅返回带有最佳选项字母的答复。然后将一些 JSON 请求参数添加到兼容的聊天完成请求中: { "max_completion_tokens": 1, "logprobs": true, "top_logprobs": 20 } LLM API 将返回字母以及模型的替代令牌的对数概率。对每个问题重复一遍。强制它只生成一个令牌可以避免冗长的答案,并且速度非常快,尽管处理输入仍然需要时间。不过,对于每个问题,如果后端支持,共享状态前缀都可以进行 KV 缓存。有趣的部分:这也适用于视觉模型。 Jev 记录的请求格式当前仅描述文本/JSON 状态。我为本地实验添加了图像附件字段。我的示例捕获网络摄像头帧,发送 base64 JPEG,并打印表格:一个人是否可见,我们是在室内还是室外,以及场景的亮度如何?在我的 RTX 3090 上使用 Gemma 4 12B 时,我每秒可以获得大约 1 帧,每帧有 3 个问题。我还针对 OpenAI gpt-6-luna 运行了它,并获得了大约 0.2 FPS。大概是因为我没有做出任何努力来避免通过他们的系统每个问题每个帧进行单独连接的成本。专业的计算机视觉模型肯定更高效,但我喜欢的是灵活性:通过以纯文本描述来更改条件。这是独立的 Python 示例(OpenCV 只是用于方便访问网络摄像头,而不是用于任何实际的计算机视觉): #!/usr/bin/env -S uv run --script # /// script # dependency = ["opencv-python"] # /// """使用 llama.cpp 或 OpenAI 预览和评分网络摄像头帧。 uv run webcam.py uv run webcam.py https://api.openai.com/v1 gpt-6-luna OpenAI 读取 OPENAI_API_KEY。 """ import argparse import base64 import concurrent.futures import datetime import json import math import mimetypes import os import pathlib import time import urllib.parse import urllib.request import cv2 #attachments 是我们对 Jev 请求格式的自定义添加。 data = json.loads(""" { "state": "检查此网络摄像头框架。仅判断明显存在的内容。", "attachments": [], "questions": { "person": { "type": "noul", "instructions": "一个人可见吗?" }, "plant": { "type": "noul", "instructions": "植物可见吗?" }, "setting": { "type": "choice", "instructions": "摄像机在哪里?", "criteria": { "indoors": null, "outdoors": null, "unclear": null } }, "light": { "type": "score", "instructions": "场景有多亮?", "criteria": [ "dark", "dim", "bright" ] } } } """) def Score(data, url, model): state = data["state"] if not isinstance(state, str): state = json.dumps(state) # 附件是我们对 Jev 风格请求格式的扩展: # 图像文件路径或 base64 数据 URL。所有问题都加载一次。 images = [] for data.get("attachments", []): if attachment.startswith("data:image/"): images.append(attachment) continue path = pathlib.Path(attachment).expanduser() mime_type, _ = mimetypes.guess_type(path) 如果 mime_type 不在 {"image/png", "image/jpeg", "image/webp", "image/gif"}: raise ValueError(f"不支持的图像文件: {path}")encoded = base64.b64encode(path.read_bytes()).decode() images.append(f"data:{mime_type};base64,{encoded}") # 仅将 API 密钥发送到 OpenAI。 is_openai = urllib.parse.urlsplit(url).hostname == "api.openai.com" headers = {"Content-Type": "application/json"} if is_openai: headers["Authorization"] = "Bearer " + os.environ["OPENAI_API_KEY"]answers = {} for name, Question in data["questions"].items(): # 表示选择,布尔值,和序数级别作为字母选项。 if Question["type"] == "choice": options = Question["criteria"] elif Question["type"] == "noul": options = {"true": None, "false": None} | Question.get("criteria", {}) elif Question["type"] == "score": options = {str(i): i 的描述,enumerate(question["criteria"])} 中的描述} else: raise ValueError(f"未知问题类型: {question['type']}") if not 2
这篇文章对您有帮助吗?

订阅66必读

每日精选科技资讯,直达你的邮箱