跳到主要内容

环境诊断与错误排查

Diagnostics 只做检查,不会帮你安装任何东西。

属性​

类别属性类型读写说明
环境supportedbool只读这台机器上的运行时是否可用
环境versionString只读版本字符串;没装任何运行时包时是空字符串
能力onnx_cpubool只读onnx-cpu 包已装好且硬件在位;缺任何一项都是 false
能力onnx_cudabool只读onnx-cuda 包已装好且硬件在位;缺任何一项都是 false
能力onnx_directmlbool只读onnx-directml 包已装好且硬件在位;缺任何一项都是 false
能力onnx_openvinobool只读onnx-openvino 包已装好且硬件在位;缺任何一项都是 false
能力onnx_trtbool只读onnx-trt 包已装好且硬件在位;缺任何一项都是 false
能力trt_nativebool只读trt-native 包已装好且硬件在位;缺任何一项都是 false
能力paddle_cpubool只读paddle-cpu 包已装好且硬件在位;缺任何一项都是 false
能力paddle_gpubool只读paddle-gpu 包已装好且硬件在位;缺任何一项都是 false
能力torchscriptbool只读torchscript 包已装好且硬件在位;缺任何一项都是 false
能力rknnbool只读rknn 包已装好且硬件在位;缺任何一项都是 false

读法​

先看 supported。如果它是 false,说明这台机器整体没有装好运行时,十个能力位全是 false 也属于这种情况,这时要先安装运行时,然后再考虑怎么选路。

配合 provider_runtime_version(id) 能分辨是缺包还是缺硬件:查得到版本记录,说明包已经装好,问题出在硬件上;报 ProviderMissing,说明包没有装。

示例:

let d = Diagnostics::new();
println!("{} {}", d.supported, d.version);
println!("{} {} {} {}", d.onnx_cpu, d.onnx_cuda, d.onnx_directml, d.onnx_openvino);
println!("{} {} {} {}", d.onnx_trt, d.trt_native, d.paddle_cpu, d.paddle_gpu);
println!("{} {}", d.torchscript, d.rknn);

ProviderIds 常量清单​

权威表 COUNT = 18,id 通过常量或函数获取。

组id
推理 ×12onnx-cpu、onnx-cuda、onnx-openvino、onnx-trt-ep、onnx-directml、trt-native、paddle-cpu、paddle-gpu、edge-rknn、tflite、onnx-tflite、torchscript-cpu
依赖资源包 ×2cudnn、cuda-libs
工具链包 ×4torch、ultralytics、openvino-intel-gpu、openvino-intel-npu

provider_id_at()​

pub fn provider_id_at(index: usize) -> Option<&'static str>

按下标取 id,返回静态字符串。下标越界返回 None。

示例:

let first = darra_ai::providers::provider_id_at(0);

provider_id_is_valid()​

pub fn provider_id_is_valid(provider_id: &str) -> bool

校验 id 是否在权威清单里,大小写不敏感。

示例:

let ok = darra_ai::providers::provider_id_is_valid("onnx-cuda");

provider_runtime_version()​

pub fn provider_runtime_version(provider_id: &str) -> Result<String, Error>

取已安装包的运行时版本,返回 JSON,缺字段写 null。载荷格式:onnx / trt-engine / openvino / rknn / paddle / torchscript。

示例:

// 返回形如 {"provider":"onnx-cuda","packVersion":"2.3.1","runtimeVersion":"1.18.0"}
let v = darra_ai::providers::provider_runtime_version("onnx-cuda")?;

错误排查方法论​

排查时先按「坏在哪里」分成三类:模型与授权、环境与运行时、推理与运行。

一、模型与授权类​

怎么判断:probe 和 open 都失败。

排查顺序:

  1. 先调 probe:路径不对就核对路径,容器文件损坏就换一份完整的模型。

二、环境与运行时类​

怎么判断:同一个模型在别的机器上能打开。诊断快照里目标能力位是 false。

排查顺序:

  1. 先跑一次诊断快照:如果 supported 是 false,说明运行时整体不可用。
  2. 缺 Provider 包就装上对应的运行时包,再试一次。

缺 Provider 包时重试不会自己好。

三、推理与运行类​

怎么判断:open 成功之后才出错。同一段代码换一张图,或者降低并发,就好了。

排查顺序:

  1. 图片读不出来就检查路径、权限和解码。

等待预算耗尽看超时设置就好,不是推理挂死。

诊断 JSON​

诊断 JSON 已做去敏处理,结构如下:

{
"schema": 1,
"sdk": { "version": "1.0.0+runtime", "abi": 65536 },
"os": { "name": "windows", "version": "10.0.26100", "arch": "x64" },
"cpu": { "model": "AMD Ryzen 7 9800X3D", "cores": 16 },
"gpus": [ { "model": "NVIDIA RTX 4070", "driver": "560.94", "cudaMax": "12.6" } ],
"providers": [ { "id": "onnx-cpu", "version": "1.0.0", "path": "C:/DARRA/Runtime/onnx-cpu/1.0.0" } ],
"license": null,
"recentErrors": [ { "code": 11, "message": "...", "when": "2026-09-01T10:00:00+08:00" } ]
}

读取契约:schema 总是存在,sdk / os / cpu 采不到写 null。没有独显时 gpus 是 [],没装包时 providers 是 []。

会话元信息 JSON​

这是 Session::meta() 的输出。排障时用它核对任务、标签、输入尺寸、实际 Provider 和授权状态:

{
"schema": 1,
"task": "detect",
"labels": ["scratch", "dent"],
"input": { "width": 640, "height": 640 },
"payloadKind": "onnx",
"provider": "onnx-cuda",
"encrypted": true,
"containerFormat": "DARM1",
"license": { "mode": "trial", "trialRemaining": 12 }
}

task 是短名:detect/classify/segment/pose/obb/ocr/anomaly/depth,认不出返回 None。

license 的取值:试用 {mode:"trial", trialRemaining},永久 {mode:"permanent"}。明文会话(encrypted=false)没有 license 键,也没有 containerFormat 键。

下面是长名到短名的对应关系(模型元数据里的任务名映射到结果里的 task):

长名(模型元数据)短名
detectiondetect
classificationclassify
segmentation / instance-segmentationsegment(两种都合并成 segment)
posepose
obbobb
ocr / ocr-text-detectionocr(两种都合并成 ocr)
anomalyanomaly
depthdepth(一一对应)

inputSizeSource / input.source 来源标记只有三个取值(各 Provider 相同):

标签含义什么时候标
graph模型里真实存在的维度 —— 模型图里确实定义了固定维度探针从模型图里读到了固定维度
containerHeader喂数据时约定的尺寸 —— 由声明通道给出。模型是动态维时,这个值不代表模型真实形状声明里有尺寸,但模型图是动态维
none两个来源都没说两个来源都没有

完整示例​

use darra_ai::Diagnostics;
use darra_ai::Error;
use darra_ai::providers::{provider_id_at, provider_id_is_valid, provider_runtime_version};

fn main() {
let d = Diagnostics::new();
println!("supported={} version={}", d.supported, d.version);
let caps = [("onnx-cpu", d.onnx_cpu), ("onnx-cuda", d.onnx_cuda)];
for (id, capable) in caps {
let pack = match provider_runtime_version(id) {
Ok(v) => v,
Err(Error::ProviderMissing { .. }) => "未装".to_string(),
Err(Error::UnsupportedPlatform { .. }) => "平台不一致".to_string(),
Err(Error::Internal { message, .. }) => format!("id 非法: {message}"),
Err(e) => format!("查版本失败: {}", e.message()),
};
println!("{id} capable={capable} pack={pack}");
}
println!("caps={}{}{}{}{}{}{}{}{}{}",
d.onnx_cpu as u8, d.onnx_cuda as u8, d.onnx_directml as u8,
d.onnx_openvino as u8, d.onnx_trt as u8, d.trt_native as u8,
d.paddle_cpu as u8, d.paddle_gpu as u8, d.torchscript as u8, d.rknn as u8);
let _ = provider_id_at(0);
assert!(provider_id_is_valid("onnx-cuda"));
}