Ultralytics LLM 接口详解:在 YOLO 视觉管线旁接入 OpenAI 兼容大语言模型
LLM 是 Ultralytics 为 ultralytics.models.llm 模块提供的一个轻量级推理接口,用于通过 OpenAI 兼容的 Responses / Chat Completions API 调用语言与视觉多模态模型。它负责把文本、图片路径或 PIL/NumPy 图像统一转换为模型请求,把请求参数原样透传给官方 OpenAI Python SDK,并返回 SDK 原生响应对象。读完本文,你将掌握如何安装配置、做纯文本问答、发送本地或远程图像、启用流式输出与异步并发调用,以及如何把 LLM 推理接到 YOLO 检测结果之后形成“视觉 + 语言”组合工作流。
定位与设计理念
从源码看,LLM 类定义在 ultralytics/models/llm.py,其类注释明确将它描述为 "OpenAI-compatible large language model interface"。核心设计与职责划分如下:
- 输入归一化:
_prepare与_image_url负责把纯文本、多模态内容、本地图像文件、HTTP URL、data URI、NumPy 数组与 PIL 图像统一整理成 OpenAI SDK 能消费的消息结构; - 参数透传:
_request把每次调用传入的**kwargs合并进请求字典,stream=True等 SDK 请求参数原样生效; - 客户端懒加载:
_get_client与_get_async_client仅在首次推理时才通过check_requirements("openai>=2.0.0")校验并导入openai库,避免无关安装负担; - 结果零包装:直接返回 SDK 原生响应对象,因此
response.output_text(Responses API)与response.choices[0].message.content(Chat Completions)等取值方式与官方文档一致。
值得注意的边界是:LLM 只做推理,不实现 train、val、export、track、benchmark,也不通过 yolo CLI 暴露。它被列入 ultralytics/models/init.py 的导出集合,并在 ultralytics/init.py 中以 from ultralytics.models import LLM 的形式成为包级 API,因而可以直接 from ultralytics import LLM 使用。
安装与环境配置
LLM 的运行时依赖为 openai>=2.0.0,被声明在 pyproject.toml 的 llm 可选依赖组中。推荐一条命令完成安装:
pip install "ultralytics[llm]"
随后为 OpenAI 设置环境变量(也可以在构造实例时显式传 api_key,二者取其一即可,源码中 _api_key 优先级更高):
export OPENAI_API_KEY="your-api-key"
构造参数一览
LLM.__init__ 的完整签名与语义如下表,所有参数与代码实现一一对应:
| 参数 | 默认值 | 说明 |
|---|---|---|
model |
"gpt-5.6-luna" |
随每次请求发送给端点的模型标识符 |
api |
"responses" |
API 格式,只能是 "responses" 或 "chat.completions",否则抛出 ValueError |
base_url |
None |
可选的 OpenAI 兼容端点地址,对接第三方或本地服务时使用 |
api_key |
None |
API 密钥;缺省时由 SDK 读取 OPENAI_API_KEY 环境变量 |
prompt |
None |
系统提示前缀,会被拼接到纯文本与图像请求的 prompt 之前 |
**kwargs |
— | 每次请求的默认 SDK 参数;单次调用传入的同名参数优先覆盖构造时的默认值 |
从 ultralytics/models/llm.py 的 _request 实现可以看到请求构造顺序:{"model": self.model, **self.overrides, **kwargs}。也就是说构造时的 **kwargs 作为请求级默认值,调用时传入的 kwargs 再行覆盖,这一机制保证了“构造一次、多样化调用”的灵活用法。
Responses API(默认)与多模态输入
Responses API 是默认格式。把 prompt 直接传给实例即可:
from ultralytics import LLM
llm = LLM("gpt-5.6-luna")
response = llm("What is YOLO?")
print(response.output_text)
LLM 天然支持视觉多模态输入。image 参数可接受:本地文件路径、HTTP(S) URL、data URI、NumPy 数组或 PIL 图像:
from ultralytics import LLM
llm = LLM("gpt-5.6-luna")
response = llm("What is happening in this image?", image="https://ultralytics.com/images/bus.jpg")
print(response.output_text)
底层对图片的处理路径值得展开说明(见 _image_url):
- 字符串且以
http://、https://或data:image/开头时原样透传,不做本地读取; - 本地路径或
Path通过cv2.imread读取; - PIL 图像先
convert("RGB")再经cv2.cvtColor(..., COLOR_RGB2BGR)转换; - 其余输入按 NumPy 数组处理,遵循 OpenCV 的 BGR 通道顺序;
- 最终统一
cv2.imencode(".jpg")编码为data:image/jpeg;base64,...data URI 提交。
因此,若你的数组是 RGB 顺序,请务必先转换为 BGR 再传入。另外注意:source 位置的字符串一律按文本处理,例如 llm("bus.jpg") 发的是文本内容,想发图片必须走 image 参数。
使用 prompt 可以给所有请求共享同一条指令前缀:
llm = LLM("gpt-5.6-luna", prompt="Answer in one sentence.")
response = llm("Describe this image.", image="bus.jpg")
Chat Completions 模式
当端点只实现 Chat Completions 时,通过 api="chat.completions" 切换,并读取其原生响应结构:
from ultralytics import LLM
llm = LLM("gpt-5.6-luna", api="chat.completions")
response = llm("What is non-maximum suppression?")
print(response.choices[0].message.content)
同样的接口同样支持多模态:
response = llm("Describe this image.", image="bus.jpg")
print(response.choices[0].message.content)
两种 API 格式在消息构造上存在差异(对应 _prepare 与 _request):Responses 模式使用顶层 input 字段与 {"type": "input_text"} / {"type": "input_image"} 内容块;Chat Completions 模式则使用 messages 字段与 {"type": "text"} / {"type": "image_url", "image_url": {"url": ...}} 内容块。这些细节已被 LLM 内部消化,使用者无需感知。
携带多轮对话历史
当你需要聊天历史时,可以直接传入原生消息对象列表,它们会被原样转发、不做任何改写(见 _prepare 对 list/tuple/dict 输入的直接返回逻辑):
history = [
{"role": "user", "content": "What tasks does YOLO support?"},
{"role": "assistant", "content": "Detection, segmentation, classification, pose, and more."},
]
response = llm(history) # 追加问题需自行在列表末尾补充新消息
流式输出与异步并发
因为请求参数是原样透传给 SDK 的,stream=True 直接可用,配合事件类型 response.output_text.delta 即可逐字输出:
llm = LLM("gpt-5.6-luna")
for event in llm("Explain object detection.", stream=True):
if event.type == "response.output_text.delta":
print(event.delta, end="", flush=True)
需要并发请求时使用 async_call(内部经由 AsyncOpenAI 懒加载客户端):
import asyncio
from ultralytics import LLM
llm = LLM("gpt-5.6-luna")
async def main():
response = await llm.async_call("What is YOLO?")
print(response.output_text)
asyncio.run(main())
同步入口 __call__ 与异步入口 async_call 共用同一套 _prepare / _request 逻辑,因此多模态、流式等所有能力在异步路径上同样适用。
接入 OpenAI 兼容的第三方或本地服务
只要服务端暴露 OpenAI 兼容的 Responses 或 Chat Completions 端点,LLM 就可以对接,例如 DeepSeek、Kimi、Z.AI GLM、OpenRouter,以及各类本地推理服务。只需把服务的 base_url、模型名与密钥填入即可:
from ultralytics import LLM
llm = LLM(
"provider-model",
api="chat.completions",
base_url="https://provider.example/v1",
api_key="your-api-key",
)
response = llm("What tasks does YOLO support?")
print(response.choices[0].message.content)
从 ultralytics/models/llm.py 的 _get_client 可见,只有非 None 的 base_url / api_key 才会被透传给 OpenAI(**kwargs),未设置时由 SDK 回落读取环境变量。不同提供方在模型命名、图像支持、请求参数与可用 API 格式上各有差异,接入前务必查阅其官方文档确认 api 参数应选 "responses" 还是 "chat.completions"。
组合实战:YOLO 检测驱动 LLM 描述
把视觉检测与大模型推理衔接是本接口最典型的使用场景:先用 YOLO 判断画面中是否有目标,再仅在必要时触发 LLM,从而节省调用成本。完整可运行示例如下:
from ultralytics import LLM, YOLO
yolo = YOLO("yolo26n.pt")
llm = LLM("gpt-5.6-luna")
image = "https://ultralytics.com/images/bus.jpg"
result = yolo(image)[0]
# 仅当 YOLO 检测到 person 时才调用 LLM。
if any(result.names[int(cls)] == "person" for cls in result.boxes.cls):
response = llm("Describe the scene.", image=image)
print(response.output_text)
在这个流程里,result.names[int(cls)] == "person" 借助了 YOLO 结果的类别索引映射,image 变量既传给 YOLO 又传给 LLM,说明同一份图像输入可以直接在两条推理链中复用。由此可以延伸出更多自动化场景:人流统计后的语义总结、安防报警时的图文事件描述、以及质量检测结果的自然语言报告等。
常见问题
LLM 支持哪些 API?
默认使用 Responses API;对只实现 Chat Completions 的端点设置 api="chat.completions" 即可。
可以用哪些服务商? OpenAI 以及一切提供兼容端点的服务均可,如 DeepSeek、Kimi、Z.AI GLM、OpenRouter 与本地推理服务,按其模型名、base_url 与密钥配置即可。
如何向多模态模型发送图片?
把 prompt 放在第一个参数,图片通过 image 传入(本地路径、URL、data URI、NumPy 数组或 PIL 图像均可)。图片支持能力取决于所选模型与提供方。
能用这个类训练或导出 LLM 吗?
不能。LLM 仅提供同步与异步推理。视觉任务的训练、验证、预测、导出、跟踪与基准测试请使用 Ultralytics 的 YOLO 系列接口。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0625
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00