推理
推理失败只设 last_error,phase 仍为 Opened。
基础用法
infer_file()
AiResult<InferenceResult> infer_file(const std::string& image_path);
AiResult<InferenceResult> infer_file(const std::string& image_path, const ImageDesc& desc);
AiResult<InferenceResult> infer_file(const std::string& image_path, const std::vector<double>& thresholds);
AiResult<InferenceResult> infer_file(const std::string& image_path, const ImageDesc& desc, const std::vector<double>& thresholds);
对磁盘上的图片做一次推理,JPG/PNG/BMP 按魔数识别,desc 可指定像素格式和裸缓冲尺寸。
参数:
image_path— 图片文件路径desc— 可选图像描述:Auto()自嗅探 /Encoded()/Rgb888(w,h,s),另有Bgr888/Gray8/Rgba8888thresholds— 可选 per-call 阈值表,空 = 用default_thresholds
示例:
auto r = ai.infer_file("D:/shots/gear_001.jpg");
if (r) for (auto& it : r.content.items) std::cout << it.label << "\n";
infer_image()
AiResult<InferenceResult> infer_image(const uint8_t* image_bytes, size_t len,
const ImageDesc& desc = ImageDesc());
AiResult<InferenceResult> infer_image(const std::vector<uint8_t>& image,
const ImageDesc& desc = ImageDesc());
AiResult<InferenceResult> infer_image(std::span<const uint8_t> image, // C++20
const ImageDesc& desc = ImageDesc());
内存图不落盘,三个重载等价(span 仅 C++20),推理要 Open 之后才可用。空图或格式不对失败,不抛异常。
参数:
image_bytes/image— 图像字节(编码流或裸像素)len— 字节数(指针重载)desc— 图像描述,缺省ImageDesc()= Auto 自嗅探thresholds— 可选 per-call 阈值表(形状同default_thresholds)
示例:
std::vector<uint8_t> jpg = ReadFileBytes("frame.jpg");
auto r = ai.infer_image(jpg, Darra::AI::ImageDesc::Auto());
并发推理
一个模型一个 Model。多模型就多个实例,不要换路径复用。实例不可拷贝。
并发可设项(workers / queue / weight)走 model.config()。Open() 前设好。
空闲机实测(197,det.onnx,3 轮中位):
- 单任务基线:1×(约 0.2s)
- 池
workers=2双投:两任务同时完成,各约 1–1.5 倍单任务 - 多实例 2–4 个:总吞吐约等于串行(0.88–0.94×) 并发收益随机器负载变化。
submit() / wait()
AiResult<uint64_t> submit(const uint8_t* bytes, size_t len, const ImageDesc& desc = ImageDesc());
AiResult<uint64_t> submit(const std::vector<uint8_t>& image, const ImageDesc& desc = ImageDesc());
AiResult<uint64_t> submit(const std::string& file_path);
AiResult<InferenceResult> wait(uint64_t ticket);
submit 入队返回 ticket,wait(ticket) 取结果。文件路径版结果壳同 infer_file。workers=1 时双投排队逐个。
workers
ModelConfig& workers(int32_t v);
int32_t workers() const;
并发路数,Open() 前设好:0/1 单会话排队,2..32 池并发,超 32 拒绝打开。默认 1。
示例:
model.config().workers(4).queue(100).weight(100);
model.Open();
auto t = model.submit(bytes, len, desc);
auto r = model.wait(t.content);
高级性能旋钮
这些可调项在高级面 darra_ai.hpp 的 SessionOptions / PoolOptions 里。
- workers(池大小):1 = 单会话(默认)。2..32 = 开池。落点
PoolOptions::max_workers(0=1,上限 32)。 - queue_capacity:仅池(workers≥2)生效。0=64,1..4096。落点
PoolOptions::queue_capacity。 - weight:0=100,1..10000,同卡并发槽份额(不是 CUDA SM%、不是优先级)。落点
SessionOptions::weight/PoolOptions::weight。 - parallel:0/1 = 单路排队。2..32 = 会话内并发(仍一份权重)。落点
SessionOptions::parallel。 - threads:限推理线程(算子内并行),
intra_op_threads/inter_op_threads,0=自动。落点SessionOptions。 - precision:
Precision枚举 Unspecified=0(跟随 Provider 默认)/ Fp32=1 / Fp16=2 / Int8=3。Int8 = 动态量化;兑现不了指定档位 = 打开失败并点名档位,禁止静默降 FP32。 - 日志出口:
GlobalLogSink(进程级单槽)。高级面等价darra_log_set_callback,未接回调 = 静默。 - global_threads:
GlobalThreads::set(intra, inter),0=自动。高级面等价runtime_configure。
槽与份额
每次 infer 占 1 槽,按在飞张数计;同卡多模型按 weight 分槽。slots = 0 时 1 个 owner 不限流,≥2 个 owner 按份额分。
推理池 darra_pool
不透明推理池指针。darra_pool_close 后指针失效(nullptr 关闭安全),submit 可多线程;DropOldest 挤掉或未完成则失败。
darra_overflow 队列满策略
池队列满时的行为,三值:
- Fail(默认)= 队列满 submit 立即失败。
- Block = 队列满 submit 等到有空位。
- DropOldest = 丢掉最旧未开跑任务,被丢者 wait 失败。
设备池 darra_device_pool
不透明设备池指针(C++ 封装 DevicePool)。一个设备池 = 同一模型跨多张 GPU 分活。票号在池内全局唯一。八个入口:
- 打开 darra_device_pool_open / open_plain:加密 / 明文模型设备池。参数 container / key / password / prefer_provider / options。options 传 nullptr = 单卡 device 0、每卡并发路 1、队列 64、Fail。
- 并发 darra_device_pool_submit:提交一张图,返回全局唯一票号。gpu_device_or_minus1 为 -1 = 按权重分活。大于等于 0 = 钉到该卡(不参与分活,卡必须在池内)。图像字节被拷走,线程安全。
- 并发 darra_device_pool_wait:等一张图的结果 JSON,用完 darra_string_free。被 DropOldest 挤掉的票失败,并计入 report.dropped。
- 并发 darra_device_pool_try_wait:非阻塞取结果,还没好就失败。
- 配置 darra_device_pool_set_device_weight:运行期改设备权重,1..10000 = 新权重。0 = 该卡停接新活(在飞继续跑)。只影响新进件。不抢占。卡必须在池内,运行期不加卡。
- 诊断 darra_device_pool_report:设备池观测。
- 打开 darra_device_pool_close:关全部内层池。不能与提交 / 等待并发。nullptr 安全。
分活按 device_weight 相对权重(权重比 ≈ 分活比,不必加和 = 100);显式钉卡的进件不参与分活。设备池必须在扫描周期外的线程里跑。
运行期错误语义
主面统一返回 AiResult<T>,失败不抛异常。失败读结果里的错误码。
阈值
per-call 阈值只覆盖本次调用,不改默认表。阈值表 = 类别下标 → 分数下限 [0,1],空 = 不过滤;长度/越界/NaN 与 class_count 对不上直接失败,不迁就。
auto inf = ai.infer_file("a.jpg", std::vector<double>{0.9});
推理结果
推理结果 envelope 字段恒定:schema / task / provider / elapsedMs / image / results。task 取值 8 项:detect / classify / segment / pose / obb / ocr / anomaly / depth。results 元素随 task 和 Provider 而变,先按键判形态再按 task 判族;承重字段缺 = 契约违反,不补默认值。
infer_tensors()
std::vector<Tensor> infer_tensors(const std::vector<Tensor>& inputs) const
多输入多输出,传入输入张量返回输出张量;输出由 SDK 分配,须用 darra_tensors_free 释放。未 Open() 或张量对不上直接失败。
参数:
inputs— 输入张量表(名称、形状、数据)