news 2026/5/1 6:06:11

YOLO12 API接口文档:POST /predict 的multipart/form-data规范详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
YOLO12 API接口文档:POST /predict 的multipart/form-data规范详解

YOLO12 API接口文档:POST /predict 的multipart/form-data规范详解

1. 为什么你需要读懂这个接口规范

你刚部署好ins-yolo12-independent-v1镜像,WebUI(7860端口)点几下就能看到检测效果——但真正要把YOLO12集成进你的业务系统,靠点鼠标可不行。
你得调API。而/predict这个接口,是整个YOLO12服务对外输出能力的唯一图像入口。它不接受base64、不认JSON body、不解析URL参数里的图片链接——它只认一种格式:multipart/form-data

很多开发者第一次调用失败,不是模型没加载、不是GPU没启动,而是卡在了“传图方式不对”:

  • curl -d发送二进制数据?→ 400 Bad Request
  • 把图片转成base64塞进JSON字段?→ 422 Unprocessable Entity
  • 用Postman选错Body类型(选了raw而非form-data)?→ 返回空响应或500

这不是YOLO12的bug,是HTTP协议层的“语言不通”。本文不讲YOLO原理,不跑训练代码,就聚焦一件事:让你用任意编程语言,100%正确地把一张图送进/predict,拿到结构化检测结果。所有细节,包括字段名、边界符、编码陷阱、常见报错,全部摊开讲。

2. POST /predict 接口核心行为与约束

2.1 接口基础信息

项目
HTTP方法POST
路径/predict
协议HTTP/1.1(支持HTTPS,若反向代理配置了SSL)
响应格式application/json(UTF-8编码)
超时设置默认30秒(从接收到完整请求体开始计时)
最大上传尺寸16MB(由FastAPI默认限制,不可热修改)

关键提醒:该接口不校验文件扩展名,但会尝试用PIL打开图像。上传.txt或损坏的.jpg会导致500错误,日志显示UnidentifiedImageError。务必确保上传的是有效图像文件。

2.2 multipart/form-data 的真实结构

别被“表单数据”这个词骗了——它和网页里填用户名密码的<form>不是一回事。它的本质是:把二进制文件和文本参数,用一串特殊分隔符(boundary)打包成一个HTTP body

一个合法的请求体长这样(已简化,仅保留关键部分):

POST /predict HTTP/1.1 Host: 192.168.1.100:8000 Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW Accept: application/json ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="file"; filename="test.jpg" Content-Type: image/jpeg <这里是test.jpg的原始二进制字节流,无任何编码> ------WebKitFormBoundary7MA4YWxkTrZu0gW--

注意三个硬性要求:

  • Content-Type必须包含boundary=参数,且值要与body中实际使用的分隔符完全一致;
  • name="file"固定字段名,不能写成imageimgupload
  • filename属性可有可无,但若存在,其值不应影响处理逻辑(YOLO12只读取二进制内容);
  • Content-Type子部分(即image/jpeg建议填写准确MIME类型,但非强制;传application/octet-stream也能成功。

2.3 支持的图像格式与预处理规则

YOLO12 API接收图像后,会自动执行以下标准化流程:

步骤操作说明
1. 解码使用PIL.Image.open()支持JPG/JPEG、PNG、WEBP;BMP需额外安装pillow-simd,不推荐
2. 转模式.convert('RGB')灰度图、RGBA图均转为3通道RGB,避免通道数不匹配
3. Resize等比缩放+补黑边 →640×640保持宽高比,短边缩至640,长边超出部分用黑色填充(YOLO标准letterbox)
4. 归一化pixel / 255.0输入张量值域变为[0,1],符合PyTorch模型预期

实测验证:上传一张1920×1080的PNG人像图,返回的bbox坐标是基于640×640推理分辨率的。如需映射回原图坐标,需按比例反算(见第4节)。

3. 各语言调用示例:避开最常见坑

3.1 Python(requests库)——最简可靠版

import requests url = "http://192.168.1.100:8000/predict" # 替换为你的实例IP image_path = "/path/to/test.jpg" # 正确:直接传file对象,requests自动构造multipart with open(image_path, "rb") as f: files = {"file": ("test.jpg", f, "image/jpeg")} # (filename, file_obj, mime_type) response = requests.post(url, files=files, timeout=30) # 错误示范(常见): # files = {"file": f.read()} # 传bytes会丢失filename和mime,导致422 # files = {"file": open(image_path, "rb")} # 缺少filename,某些旧版requests会失败 if response.status_code == 200: result = response.json() print(f"检测到 {len(result['predictions'])} 个目标") for pred in result["predictions"]: print(f"- {pred['class_name']}: {pred['confidence']:.2f} @ [{pred['x1']}, {pred['y1']}, {pred['x2']}, {pred['y2']}]") else: print(f"请求失败: {response.status_code} - {response.text}")

3.2 JavaScript(Fetch API)——浏览器/Node.js通用

async function predictImage(fileInput) { const url = "http://192.168.1.100:8000/predict"; const formData = new FormData(); // 正确:使用input.files[0],保留原始文件名和类型 formData.append("file", fileInput.files[0]); try { const response = await fetch(url, { method: "POST", body: formData, // 自动设置Content-Type和boundary // 不要手动设置headers!否则会覆盖boundary }); if (!response.ok) throw new Error(`HTTP ${response.status}`); const result = await response.json(); console.log("检测结果:", result); return result; } catch (err) { console.error("调用失败:", err); } } // 调用示例(绑定到HTML <input type="file">) document.getElementById("upload").addEventListener("change", (e) => { predictImage(e.target); });

3.3 cURL命令行——调试黄金组合

# 终极可靠写法(显式指定boundary,兼容所有curl版本) curl -X POST "http://192.168.1.100:8000/predict" \ -H "accept: application/json" \ -F "file=@/path/to/test.jpg;type=image/jpeg" \ -v # 加-v看详细请求头和body # 危险写法(易出错): # curl -X POST ... -d "@test.jpg" # 传的是raw body,不是multipart # curl -X POST ... -H "Content-Type: multipart/form-data" # 缺少boundary,服务无法解析

调试技巧:加-v参数后,curl会打印完整的请求头和body。重点检查:

  • Content-Type: multipart/form-data; boundary=------------------------...是否存在
  • body中是否有Content-Disposition: form-data; name="file"; filename="test.jpg"
  • 二进制数据前是否有空行(\r\n\r\n

4. 响应JSON结构详解与坐标映射指南

4.1 标准响应字段说明

成功响应(HTTP 200)返回标准JSON,结构如下:

{ "status": "success", "predictions": [ { "class_id": 0, "class_name": "person", "confidence": 0.924, "x1": 128.3, "y1": 45.7, "x2": 210.8, "y2": 320.1 }, { "class_id": 2, "class_name": "car", "confidence": 0.871, "x1": 412.5, "y1": 288.9, "x2": 598.2, "y2": 375.6 } ], "input_size": { "width": 640, "height": 640 } }
字段类型说明
statusstring固定为"success",失败时返回其他状态码(如400/500)
predictionsarray检测到的所有目标列表,按置信度降序排列
class_idintegerCOCO类别ID(0=person, 1=bicycle, 2=car...)
class_namestring对应的英文类别名(小写,无空格)
confidencefloat检测置信度(0.0~1.0),受请求时conf参数影响
x1,y1,x2,y2float边界框左上角(x1,y1)和右下角(x2,y2)坐标,单位:像素
input_sizeobject模型实际接收的输入尺寸(恒为{"width":640,"height":640}

4.2 如何把640×640坐标映射回原图

YOLO12返回的坐标是基于640×640推理图的。如果你的原图是1280×720,需要做逆letterbox变换

def map_bbox_to_original(pred, orig_w, orig_h): # 1. 计算letterbox填充比例 r = min(640 / orig_w, 640 / orig_h) # 缩放比例 new_unpad_w = int(round(orig_w * r)) new_unpad_h = int(round(orig_h * r)) pad_w = 640 - new_unpad_w # 左右总填充 pad_h = 640 - new_unpad_h # 上下总填充 # 2. 去除填充(坐标平移) x1 = max(0, (pred["x1"] - pad_w / 2) / r) y1 = max(0, (pred["y1"] - pad_h / 2) / r) x2 = min(orig_w, (pred["x2"] - pad_w / 2) / r) y2 = min(orig_h, (pred["y2"] - pad_h / 2) / r) return {"x1": x1, "y1": y1, "x2": x2, "y2": y2} # 示例:原图1280×720,预测框在640×640图上是[100,50,200,150] orig_bbox = map_bbox_to_original( {"x1":100, "y1":50, "x2":200, "y2":150}, orig_w=1280, orig_h=720 ) print(orig_bbox) # {'x1': 200.0, 'y1': 100.0, 'x2': 400.0, 'y2': 300.0}

关键结论:YOLO12不做“智能缩放”,它严格遵循YOLO标准letterbox流程。只要按此公式反算,100%还原原图坐标。

5. 高级用法:置信度阈值与模型切换控制

5.1 动态调整置信度阈值(conf)

虽然WebUI提供滑块,但API也支持运行时控制——通过URL查询参数

# 将置信度阈值设为0.4(更严格,减少误检) curl -X POST "http://192.168.1.100:8000/predict?conf=0.4" \ -F "file=@test.jpg" # 设为0.1(更宽松,召回更多目标) curl -X POST "http://192.168.1.100:8000/predict?conf=0.1" \ -F "file=@test.jpg"
  • conf参数范围:0.01~0.99(超出范围将被截断为最近合法值)
  • 未提供时,默认值为0.25(与WebUI初始值一致)
  • 该参数不影响模型加载或显存占用,纯CPU侧过滤,无性能损耗

5.2 模型规格切换(需重启服务)

注意:模型切换不是API参数,而是服务启动时的环境变量配置。这意味着:

  • 你不能在一次API请求中指定“这次用nano,下次用xlarge”;
  • 所有API请求共享同一个已加载的模型实例;
  • 切换模型必须:修改环境变量 → 重启服务 → 等待权重加载完成(约3-5秒)。

操作步骤(在镜像内终端执行):

# 1. 设置新模型(例如切到small版) export YOLO_MODEL=yolov12s.pt # 2. 重启服务(自动加载新权重) bash /root/start.sh # 3. 验证是否生效(查看日志末尾) tail -n 10 /root/logs/start.log # 成功日志:"Loaded model: yolov12s.pt (19.2MB) on cuda:0"

验证技巧:调用API后检查响应中的input_size不变,但predictions数量和置信度分布会变化——small版通常比nano版多检出10%~15%的低置信目标。

6. 故障排查清单:5分钟定位90%问题

遇到调用失败?按此顺序快速检查:

现象可能原因快速验证方法解决方案
HTTP 400 Bad Requestfile字段名拼错、未传文件、文件为空curl -v看请求体是否含name="file"检查代码中files键名,确认文件对象非None
HTTP 422 Unprocessable EntityContent-Type头缺失或错误、boundary不匹配curl -v确认header含multipart/form-data; boundary=删除手动设置的Content-Type头,让客户端自动生成
HTTP 500 Internal Server Error图片损坏、非支持格式、内存不足查看/root/logs/api.log末尾错误栈file test.jpg确认格式;换一张已知正常的图重试
响应为空或超时实例未启动、端口被防火墙拦截、GPU显存不足curl -I http://IP:8000/docs看是否返回200检查实例状态;nvidia-smi看GPU内存;netstat -tuln | grep 8000
检测结果为空([])图像全黑/全白、目标过小(<16px)、置信度过高降低conf参数至0.1重试;用WebUI上传同一张图对比调整conf;确认图像内容符合COCO类别

🛠终极诊断命令(在镜像内执行):

# 查看API服务实时日志(滚动跟踪) tail -f /root/logs/api.log # 检查模型是否加载成功 grep "Loaded model" /root/logs/start.log # 测试本地API连通性(绕过网络) curl -X POST "http://localhost:8000/predict" -F "file=@/root/test.jpg"

7. 总结:掌握接口规范就是掌握集成主动权

你不需要成为YOLO专家,也能把目标检测能力稳稳接入自己的系统。本文拆解的不是抽象概念,而是可立即验证、可逐行调试、可跨语言复用的具体规范

  • multipart/form-data不是玄学,它就是带boundary的二进制包裹,name="file"是唯一钥匙;
  • 所有坐标都基于640×640,但逆letterbox公式给你原图精度;
  • conf参数让你在灵敏度和准确率间自由滑动,无需改一行模型代码;
  • 模型切换虽需重启,但5秒加载+软链设计,让A/B测试成本趋近于零。

当你下次面对安防摄像头流、电商商品图、工业质检样本时,心里清楚:
只要构造对那个file字段,剩下的,交给YOLO12。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/20 6:47:13

MTools实操手册:处理含emoji/特殊符号/乱码文本时的清洗与容错策略

MTools实操手册&#xff1a;处理含emoji/特殊符号/乱码文本时的清洗与容错策略 1. 为什么你需要关注文本清洗这件事 你有没有遇到过这样的情况&#xff1a;复制一段带表情的社交媒体文案&#xff0c;粘贴进MTools里点击“执行”&#xff0c;结果页面卡住、返回空结果&#xf…

作者头像 李华
网站建设 2026/4/18 20:12:27

3种免费访问方案实现内容解锁:信息获取自由的技术指南

3种免费访问方案实现内容解锁&#xff1a;信息获取自由的技术指南 【免费下载链接】bypass-paywalls-chrome-clean 项目地址: https://gitcode.com/GitHub_Trending/by/bypass-paywalls-chrome-clean 在信息爆炸的时代&#xff0c;付费墙成为知识获取的主要障碍。本文将…

作者头像 李华
网站建设 2026/4/27 12:05:09

Qwen2.5-Coder-1.5B与C++开发实战:高性能计算项目

Qwen2.5-Coder-1.5B与C开发实战&#xff1a;高性能计算项目 如果你正在寻找一个轻量级、高性能的代码助手来帮你搞定C高性能计算项目&#xff0c;那Qwen2.5-Coder-1.5B可能就是你一直在找的那个“秘密武器”。它只有1.5B参数&#xff0c;对硬件要求不高&#xff0c;但在代码生…

作者头像 李华
网站建设 2026/4/23 17:47:25

OFA-large模型实战:构建图文匹配能力评测基准与自动化测试集

OFA-large模型实战&#xff1a;构建图文匹配能力评测基准与自动化测试集 1. 为什么需要图文匹配能力的评测基准 你有没有遇到过这样的情况&#xff1a;AI系统说一张图里有“一只猫”&#xff0c;但你仔细看发现其实是只兔子&#xff1f;或者电商平台上商品图显示的是蓝色T恤&…

作者头像 李华
网站建设 2026/5/1 5:27:50

系统优化工具3步焕新:让Windows 11运行如飞的实用指南

系统优化工具3步焕新&#xff1a;让Windows 11运行如飞的实用指南 【免费下载链接】Win11Debloat 一个简单的PowerShell脚本&#xff0c;用于从Windows中移除预装的无用软件&#xff0c;禁用遥测&#xff0c;从Windows搜索中移除Bing&#xff0c;以及执行各种其他更改以简化和改…

作者头像 李华