跳到主要内容

推理

推理失败只设 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 / Rgba8888
  • thresholds — 可选 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 — 输入张量表(名称、形状、数据)