news 2026/9/15 13:58:43

darktable AI 子系统开发指南:基于 ONNX Runtime 的推理后端架构与实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
darktable AI 子系统开发指南:基于 ONNX Runtime 的推理后端架构与实战

darktable AI 子系统开发指南:基于 ONNX Runtime 的推理后端架构与实战

【免费下载链接】darktabledarktable is an open source photography workflow application and raw developer项目地址: https://gitcode.com/GitHub_Trending/da/darktable

darktable 的 AI 子系统(AI Subsystem)是一套以 ONNX Runtime 为唯一推理后端的模块化框架,支撑交互式对象蒙版(SAM/SegNext)、神经降噪(RGB 域与 Raw 域)以及超分辨率放大等功能。本文以 dev-doc/AI.md 为核心,结合仓库源码深入剖析其三层架构、执行提供者(Execution Provider)解析、模型注册表与下载机制,并给出从零添加一个全新 AI 任务(Task)的完整步骤。读完本文,你将掌握 darktable AI 功能从模型加载、推理调度到接入 UI 的全链路开发方法。


一、架构总览:三层解耦的 AI 子系统

darktable 的 AI 子系统在逻辑上分为三层,职责清晰、依赖单向:

src/ai/ ONNX Runtime 后端(darktable_ai 静态库) backend.h 公共 API:类型定义、模型加载、推理 backend_common.c 环境、模型注册表、provider 解析 backend_onnx.c ONNX Runtime C API 封装 src/common/ai/ 高层 AI 模块(编译进 lib_darktable) segmentation.c/.h SAM/SegNext 交互式蒙版 restore.c/.h 通用 env/ctx 生命周期 + 模型加载器 restore_common.h restore_* 共享的私有结构体定义 restore_rgb.c/.h RGB 路径降噪 + 放大(分块推理、阴影提升、DWT 细节恢复) restore_raw_bayer.c/.h RawNIND Bayer 降噪(批处理 + 管道预览) restore_raw_linear.c/.h RawNIND linear/X-Trans 降噪 src/common/ai_models.c/.h 模型注册表、下载、偏好设置集成 src/gui/preferences_ai.c AI 偏好设置页签

关键分离原则src/ai/是一个完全自包含的静态库,不依赖任何 darktable 核心(只依赖 GLib 与 ONNX Runtime),这使得后端可以被独立测试和复用;而src/common/ai/负责把 AI 后端与 darktable 核心 API(DWT 小波、图像缓冲区、配置系统等)桥接起来,并仅在USE_AI=ON时编译。从 src/ai/backend.h 可以看到,后端头文件只包含<stdint.h><glib.h>,印证了这一自包含设计。

构建标志(Build Flags)

Flag默认值作用
USE_AIOFF启用 AI 子系统
USE_AI_DOWNLOADON(当USE_AI开启时)允许从仓库下载模型

USE_AI=ON时,预处理器会定义HAVE_AI;启用下载时还会定义HAVE_AI_DOWNLOAD。在 src/common/ai_models.h 中,下载相关 API 全部包裹在#ifdef HAVE_AI_DOWNLOAD之内,说明下载能力是可选特性。

运行时开关:默认关闭,懒初始化

AI 功能在偏好设置中默认关闭。当关闭时:

  • 不加载任何 ONNX Runtime;
  • 不创建、不扫描任何模型目录;
  • 所有dt_ai_env_init()/dt_ai_load_model()调用直接返回 NULL;
  • 依赖 AI 的模块通过reload_defaults()隐藏自身入口。

用户可在偏好设置 -> AI -> "enable AI features"中启用。启用后的初始化是延迟进行的:dt_ai_models_init_lazy()负责在运行时重新启用 AI 时执行延迟初始化(创建目录、读取 provider 配置、加载模型注册表、扫描本地模型),无需重启 darktable。对应实现见 src/common/ai_models.h 的注释与声明。


二、ONNX Runtime 集成:从加载到推理

2.1 初始化:进程级单例 + 懒加载

ONNX Runtime 通过 GLib 的g_once()单例机制懒初始化:

  • g_ortOrtApi指针(每进程一份);
  • g_envOrtEnv实例(每进程一份)。

两者在首次模型加载或 provider 探测时创建,并在进程生命周期内常驻。

在 Linux 上,ONNX Runtime 始终通过g_module_open()懒加载,而非在进程启动时静态链接。这样做的目的是防止 GPU provider 库(如 MIGraphX/ROCm)在进程启动阶段就初始化——在不支持的 GPU 上,这些库可能在 darktable 有机会检查偏好设置之前就abort()崩溃。

2.2 模型加载调用链

dt_ai_load_model(env, model_id, model_file, provider) -> dt_ai_load_model_ext(env, model_id, model_file, provider, opt_level, dim_overrides, n_overrides) -> dt_ai_onnx_load_ext(model_dir, model_file, provider, opt_level, dim_overrides, n_overrides)

加载一个模型的完整流程(对应 src/ai/backend_common.c 中dt_ai_load_model_ext的实现):

  1. 解析 provider:将DT_AI_PROVIDER_CONFIGURED/DT_AI_PROVIDER_AUTO解析为具体 EP,并在此处统一应用模型声明的cpu_only安全约束;
  2. 解析图优化级别DT_AI_OPT_DEFAULT时读取模型 manifest 中的ort_optimization,任何具体级别都是对 manifest 的显式覆盖;
  3. 通过环境中的模型注册表把model_id解析为目录路径;
  4. 创建OrtSessionOptions,开启全核 intra-op 并行
  5. 设置图优化级别(Graph Optimization Level);
  6. 应用符号维度覆盖(针对动态形状模型);
  7. 调用_enable_acceleration()挂接选定的执行提供者;
  8. .onnx文件创建OrtSession
  9. 内省所有输入/输出的名称、类型与形状;
  10. 检测动态输出形状(任一维度 <= 0),以启用 ORT 内部分配输出模式。

注意dt_ai_load_model()只是dt_ai_load_model_ext()的便捷封装,默认参数为DT_AI_OPT_DEFAULT, NULL, 0(见 src/ai/backend_common.c)。

2.3 推理接口dt_ai_run与张量描述符

调用方通过dt_ai_tensor_t数组传入输入、接收输出:

typedef struct dt_ai_tensor_t { void *data; // 指向原始数据缓冲 dt_ai_dtype_t type; // 元素数据类型 int64_t *shape; // 维度数组 int ndim; // 维度数量 } dt_ai_tensor_t;

该结构(定义于 src/ai/backend.h)不包含字节长度字段——缓冲长度由shape各维度乘积乘以sizeof(elem)隐式确定;datashape指针均为借用,后端在dt_ai_run期间不会拷贝它们,调用方负责分配足够空间。辅助函数dt_ai_tensor_element_count()可计算形状对应的元素个数。

dt_ai_run()透明处理两个特殊场景:

  • Float16 自动转换:若调用方提供 Float32 数据而模型期望 Float16,后端在推理前即时转换(输出方向同理);
  • 动态输出形状:若任一输出带符号维度,ORT 在内部分配输出张量。推理完成后,后端把数据拷贝到调用方缓冲,并用实际维度回写调用方的 shape 数组

2.4 图优化级别(Graph Optimization Levels)

级别枚举值适用场景
AllDT_AI_OPT_ALL默认、最快,适用于大多数模型
BasicDT_AI_OPT_BASIC仅做常量折叠 + 冗余节点消除。SAM2 decoder必须使用(激进的优化会在动态维度上破坏形状推断)
DisabledDT_AI_OPT_DISABLED预留,暂未使用

在 src/ai/backend.h 中还有一个额外的哨兵值DT_AI_OPT_DEFAULT = -1:由dt_ai_load_model传入时表示"读取 manifest 的ort_optimization字段(缺省回退 ALL)";而dt_ai_load_model_ext的调用方传具体级别即可覆盖 manifest。

2.5 符号维度覆盖(Symbolic Dimension Overrides)

带符号维度的模型(例如 SAM2 decoder 的num_labels)会让 ONNX Runtime 的形状推断失败。此时应使用dt_ai_load_model_ext()配合dt_ai_dim_override_t绑定具体值:

dt_ai_dim_override_t overrides[] = { { "num_labels", 1 } }; ctx = dt_ai_load_model_ext(env, id, file, provider, DT_AI_OPT_BASIC, overrides, 1);

dt_ai_dim_override_t结构(src/ai/backend.h)只有name(符号维度名,如"num_labels")与value(具体值)两个字段。注意name指针只在加载调用期间被读取,后端会自行拷贝所需内容,调用方可在加载返回后立即释放字符串。


三、执行提供者(Execution Providers)

3.1 Provider 表

Provider枚举配置字符串平台
AutoDT_AI_PROVIDER_AUTOauto全部
CPUDT_AI_PROVIDER_CPUCPU全部
Apple CoreMLDT_AI_PROVIDER_COREMLCoreMLmacOS
NVIDIA CUDADT_AI_PROVIDER_CUDACUDALinux, Windows
AMD MIGraphXDT_AI_PROVIDER_MIGRAPHXMIGraphXLinux
Intel OpenVINODT_AI_PROVIDER_OPENVINOOpenVINOLinux, Windows, macOS (x86_64)
Windows DirectMLDT_AI_PROVIDER_DIRECTMLDirectMLWindows

在 src/ai/backend_common.c 的dt_ai_providers[]表中可以直观看到每个 provider 的config_stringdisplay_name编译期平台守卫#if defined(...)控制的available字段)。available决定哪些 provider 出现在 UI 中;运行时是否真的可用会另行探测(见 3.4 节)。

此外,DT_AI_PROVIDER_CONFIGURED#define,值为 -1,见 src/ai/backend.h)是dt_ai_load_model()/dt_ai_load_model_ext()哨兵值:它会在调用时从darktablerc读取用户的 provider 偏好。它不是真实 provider,绝不能存入配置或 provider 表。消费方遵循两条规则:需要尊重用户设置(如 restore、segmentation)就传CONFIGURED;需要强制特定 EP(如强制 decoder 走 CPU)就直传该 EP。

3.2 自动探测策略(AUTO)

当用户选择DT_AI_PROVIDER_AUTO(或从CONFIGURED解析得到 AUTO)时,后端优先尝试平台原生加速,失败则优雅回退:

  • macOS:CoreML -> CPU
  • Windows:DirectML -> CPU
  • Linux:CUDA -> MIGraphX -> ROCm(legacy)-> CPU

3.3 运行时 Provider 加载

Provider 函数通过运行时动态符号查找加载(Unix 上用GModule/dlsym,Windows 上用GetProcAddress),从已链接的 ONNX Runtime 共享库中解析。这带来三个好处:

  • 无编译期对 provider 专属头文件的依赖;
  • provider 是可选的——缺失的符号被优雅处理;
  • 同一份二进制同时兼容 CPU-only 与 GPU-enabled 的 ORT 构建

3.4 Provider 探测:dt_ai_probe_provider()

dt_ai_probe_provider()在不加载模型的前提下测试某 provider 能否在运行时初始化。它创建临时的OrtSessionOptions,尝试挂接 provider,返回 1(可用)或 0(不可用)。偏好设置 UI 用它来在用户选中不可用的 provider 时给出警告。

3.5 多 GPU 设备选择(逃生通道)

对于同一厂商有多张 GPU 的系统(如笔记本的 iGPU+dGPU,或双 NVIDIA 卡工作站),默认device_id0(平台枚举的第一块)。高级用户可通过配置键或环境变量覆盖(同时设置时环境变量优先):

Provider配置键环境变量
CUDAplugins/ai/cuda_device_idDT_CUDA_DEVICE_ID
MIGraphX / ROCmplugins/ai/migraphx_device_idDT_MIGRAPHX_DEVICE_ID
DirectMLplugins/ai/dml_device_idDT_DML_DEVICE_ID

索引语义遵循各 provider 自身的枚举方式:

  • CUDA索引与nvidia-smi一致(并尊重CUDA_VISIBLE_DEVICES);
  • MIGraphX / ROCm索引对应rocminfo中的 GPU agent 顺序;
  • DirectML索引对应IDXGIFactory1::EnumAdapters1顺序。

OpenVINO 与 CoreML 是单设备或自管理,不读取 device_id 键。修改后需重启 darktable 生效。后端提供了dt_ai_device_id_changed_since_load()等辅助函数来检测"配置已变但进程内 ORT 仍是旧状态"的情形(见 src/ai/backend.h)。

3.6 ONNX Runtime 发行包来源

平台包来源包含的 Providers
macOSGitHub releases(CPU)CPU、CoreML(经 Apple frameworks)
Linux (x86_64)GitHub releases(GPU)CPU、CUDA、TensorRT
Linux (aarch64)GitHub releases(CPU)仅 CPU
Linux系统包(发行版)仅 CPU(Debian/Ubuntu/Fedora 的包不含 GPU provider)
WindowsNuGet(DirectML 变体)CPU、DirectML

构建系统 cmake/modules/FindONNXRuntime.cmake 在系统找不到 ONNX Runtime 时会自动下载合适的包:Linux x86_64 默认下载 GPU 变体以启用 CUDA 加速;而系统包(如 Debian/Ubuntu 的libonnxruntime-dev)仅含 CPU,不含 GPU provider。


四、模型发现与注册表(Model Registry)

4.1 目录布局

模型通过扫描子目录中的config.json被发现,扫描路径为:

  1. 传入dt_ai_env_init()的自定义路径(分号分隔);
  2. <user_data_dir>/darktable/models/
    • Linux:~/.local/share/darktable/models/
    • Windows:%APPDATA%\darktable\models\
    • macOS:~/.local/share/darktable/models/

重复 ID 以先发现者为准(重复项被跳过)。模型下载(ai_models.c)也解压到同一路径,因此下载的模型立即可被发现。扫描实现见 src/ai/backend_common.c 的_scan_directory/_scan_all_paths:逐个读取config.json解析字段,并用哈希表model_paths记录id -> 路径映射以去重。

用户还可以通过配置键plugins/ai/models_path覆盖模型目录(dt_ai_resolve_models_path_override()支持~展开,见 src/ai/backend_common.c)。

4.2 config.json 格式

每个模型目录必须包含config.json

{ "id": "mask-object-segnext-b2hq", "name": "mask segnext vitb-sax2 hq", "description": "SegNext ViT-B SAx2 HQ fine-tuned for interactive masking", "task": "mask", "arch": "segnext", "backend": "onnx" }
字段必填默认值说明
id--唯一标识符
name--UI 中显示的展示名
description""简短描述
task"general"任务类型:"denoise""upscale""mask""depth"
backend"onnx"后端类型(目前仅支持"onnx"
arch""模型架构(如"sam2""segnext"
num_inputs1模型输入数量

除了这些基础字段,后端还支持一组可选行为提示,存放在attributes对象中,例如:

"attributes": { "shadow_boost": true, "tile_factor": 1.5, "color_space": "sRGB" }

dt_ai_model_attribute_*系列访问器(src/ai/backend.h)会按需解析 JSON:缺失的键或类型不符的键返回传入的默认值(bool/string 变体返回 FALSE/NULL)。dt_ai_model_attribute_string()支持点分路径(如"variants.bayer.onnx"),中间段必须是 JSON 对象,实现见 src/ai/backend_common.c。

类似地,manifest 还可以声明cpu_only(数组或按 onnx 文件名 stem 分组的对象,声明哪些 EP 对模型不安全)、coreml_format"neuralnetwork""mlprogram")、ort_optimizationort_optimization_provider(按 provider 覆盖图优化级别)。这些字段会被后端序列化为 JSON 字符串存入dt_ai_model_info_t(src/ai/backend.h)。

4.3 模型 ID 命名约定

模式:<task>-<model>[-<size>]

  • 全部小写、连字符分隔;
  • 第一个组件是任务类型(denoisemaskupscaledepth);
  • 蒙版任务的第二个组件是子任务(object);
  • 存在多种尺寸时追加尺寸后缀(smallbaselarge)。

示例:denoise-nindmask-object-sam21-smallupscale-bsrganmask-depth-da2-small

当前仓库内置的模型目录 data/ai_models.json 包含:mask-object-sam21-smallmask-object-segnext-b2hqdenoise-nindrawdenoise-nindupscale-realplksr五个条目,每个都带min_versiondefault标记。


五、模型仓库(darktable-ai)与下载机制

darktable 中可下载的模型作为 release 资产托管在darktable-ai 仓库中。该仓库还包含:

  • 转换脚本——将 PyTorch 模型导出为 darktable 期望格式的 ONNX(正确的 I/O 名称、动态轴、把插值烘焙进计算图等);
  • 打包脚本——把config.json+ ONNX 文件打包为.dtmodel归档(zip)用于分发;
  • 模型元数据——ai_models.json源文件,列出所有可用模型及其任务、描述、资产文件名。

下载流程:

  1. darktable 读取随构建分发的 data/ai_models.json,得知存在哪些模型;
  2. 用户在 AI 偏好设置中点击"下载";
  3. ai_models.c通过 GitHub API 从 darktable-ai 最新 release 拉取.dtmodel资产;
  4. 归档解压到~/.local/share/darktable/models/
  5. 模型立即被dt_ai_env_init()发现。

仓库在darktablerc中配置:

plugins/ai/repository=darktable-org/darktable-ai

从 src/common/ai_models.h 可以看到,仓库可以额外发布未包含在捆绑目录中的模型versions.json是 release 内容的超集),支持第三方仓库(plugins/ai/third_party_repositories)与 sha256 校验和验证;模型还有DT_AI_MODEL_UPDATE_AVAILABLE/DT_AI_MODEL_UPDATE_REQUIRED的版本状态机——UPDATE_REQUIRED表示当前代码无法使用已安装模型,UPDATE_AVAILABLE只是软提示。

向仓库添加新模型

  1. 用转换脚本把模型导出为 ONNX(或参照现有示例编写新脚本);
  2. 创建带正确idtaskarch字段的config.json
  3. 打包为.dtmodel归档;
  4. 在 darktable-ai 的ai_models.json中新增模型条目;
  5. 发布新 release,并把.dtmodel作为资产附上;
  6. 更新 darktable 源码中的 data/ai_models.json,加入新模型条目。

用户也可以从本地.dtmodel文件安装模型:dt_ai_models_install_local()(src/common/ai_models.h)接受 zip 归档路径。


六、如何添加一个全新的 AI 功能

这是 dev-doc/AI.md 的核心实战章节,完整步骤如下。

Step 1:创建 AI 模块

src/common/ai/下创建你的处理模块。使用不透明类型(opaque types)封装,模块内部包装ai/backend.hdt_ai_*调用,对外暴露干净的公共 API:

// src/common/ai/your_task.h #pragma once #include <glib.h> typedef struct dt_your_task_env_t dt_your_task_env_t; typedef struct dt_your_task_ctx_t dt_your_task_ctx_t; dt_your_task_env_t *dt_your_task_env_init(void); void dt_your_task_env_destroy(dt_your_task_env_t *env); dt_your_task_ctx_t *dt_your_task_load( dt_your_task_env_t *env); void dt_your_task_free(dt_your_task_ctx_t *ctx); gboolean dt_your_task_available( dt_your_task_env_t *env); int dt_your_task_process( dt_your_task_ctx_t *ctx, const float *in, float *out, int width, int height);
// src/common/ai/your_task.c #include "common/ai/your_task.h" #include "ai/backend.h" #include "common/ai_models.h" #define TASK_KEY "your_task" struct dt_your_task_env_t { dt_ai_environment_t *ai_env; }; struct dt_your_task_ctx_t { dt_ai_context_t *ai_ctx; dt_your_task_env_t *env; }; dt_your_task_ctx_t *dt_your_task_load( dt_your_task_env_t *env) { if(!env) return NULL; char *model_id = dt_ai_models_get_active_for_task(TASK_KEY); if(!model_id || !model_id[0]) { g_free(model_id); return NULL; } dt_ai_context_t *ai_ctx = dt_ai_load_model( env->ai_env, model_id, NULL, DT_AI_PROVIDER_CONFIGURED); g_free(model_id); if(!ai_ctx) return NULL; dt_your_task_ctx_t *ctx = g_new0(dt_your_task_ctx_t, 1); ctx->ai_ctx = ai_ctx; ctx->env = env; return ctx; } int dt_your_task_process( dt_your_task_ctx_t *ctx, const float *in, float *out, int width, int height) { // prepare input tensor (convert colorspace, layout) // call dt_ai_run(ctx->ai_ctx, ...) // post-process output return 0; }

这段示例揭示了一条关键约定:dt_ai_models_get_active_for_task(TASK_KEY)(定义于 src/common/ai_models.h)按任务从集中式配置键plugins/ai/models/active/{task}解析当前激活的模型;若未设置则回退到该任务的默认下载模型,并写回配置键。加载时传入DT_AI_PROVIDER_CONFIGURED,让 provider 决策尊重用户偏好。

Step 2:注册进构建系统

在 src/CMakeLists.txt 的USE_AI分支中添加源文件:

FILE(GLOB SOURCE_FILES_AI "common/ai_models.c" "common/ai/segmentation.c" "common/ai/restore.c" "common/ai/restore_rgb.c" "common/ai/restore_raw_bayer.c" "common/ai/restore_raw_linear.c" "common/ai/your_task.c" # add here ... )

Step 3:添加模型条目

在 data/ai_models.json 中添加模型:

{ "id": "your-task-model-name", "name": "your task model name", "description": "description of the model", "task": "your_task", "github_asset": "your-task-model-name.dtmodel", "default": true }

.dtmodel文件是一个 zip/tar 归档,内含config.json和 ONNX 模型文件(一个包可含多个 ONNX,如 rawdenoise 的model_bayer.onnx+model_linear.onnx)。

Step 4:创建 UI 消费方

  • lighttable 模块:创建src/libs/your_module.c
  • darkroom IOP:创建src/iop/your_module.c

UI 模块只能包含你的src/common/ai/头文件——绝不直接包含ai/backend.hcommon/ai_models.h,以维持分层边界:

#include "common/ai/your_task.h" // in gui_init or job startup: dt_your_task_env_t *env = dt_your_task_env_init(); // check availability: gboolean avail = dt_your_task_available(env); // process: dt_your_task_ctx_t *ctx = dt_your_task_load(env); dt_your_task_process(ctx, input, output, w, h); dt_your_task_free(ctx);

七、可用任务一览与消费方

任务任务键API消费方
对象蒙版"mask"src/common/ai/segmentation.hsrc/develop/masks/object.c
Raw 降噪(Bayer)"rawdenoise"src/common/ai/restore_raw_bayer.hsrc/libs/neural_restore.c
Raw 降噪(Linear)"rawdenoise"src/common/ai/restore_raw_linear.hsrc/libs/neural_restore.c
降噪"denoise"src/common/ai/restore_rgb.hsrc/libs/neural_restore.c
放大"upscale"src/common/ai/restore_rgb.hsrc/libs/neural_restore.c

各任务的具体模型要求、I/O 规格、分块(tiling)策略、色彩空间约定、ONNX 导出说明与 config.json 示例,详见配套参考文档AI_Tasks.md。摘要如下:

  • 对象蒙版(mask):SAM 2.1 与 SegNext 两种架构。图片先被导出为 sRGB uint8,经 SAM encoder 编码为图像嵌入(每图一次、带缓存与磁盘缓存),用户点击放置前景/背景点后,轻量 decoder 产出蒙版;前一低分辨率蒙版会反馈回 decoder 做迭代精化(has_mask_input区分首击 0.0 与精化 1.0)。dt_seg_reset_prev_mask()只清蒙版缓存,dt_seg_reset_encoding()清全部(换图时调用)。SAM2 decoder 输出带num_labels符号维度,因此需要用DT_AI_OPT_BASIC+ 维度覆盖加载;
  • Raw 降噪(rawdenoise):在 darktable 管线之前对 raw CFA 马赛克做传感器级降噪,输出 DNG 再导入,可被完整管线正常调色。Bayer 变体把 2T×2T CFA 块打包为 4 通道 T×T 张量(RGGB 顺序,非 RGGB 传感器强制裁剪到 RGGB 原点),模型内部经 PixelShuffle 去马赛克后输出 3 通道 camRGB;Linear 变体(X-Trans、Foveon 等)先跑最小 darktable 管线(rawprepare→highlights→demosaic)得到 3 通道浮点,再经lin_rec2020矩阵与曝光提升后推理;
  • 降噪(denoise):对完整管线导出的线性 Rec.709 图像做 sRGB 域推理,可选 DWT 小波细节恢复把原始细纹理混合回结果,输出 TIFF(内嵌 ICC 与 EXIF)后自动导入;
  • 放大(upscale):2x/4x 超分辨率,同一模型可经model_x2.onnx/model_x4.onnx提供两种倍率,TIFF 输出采用逐扫描线流式写入以应对超大输出(4x 放大 6000 万像素原图约需 3.6GB 内存)。

neural-restore 消费方(denoise / upscale / rawdenoise)会把输出写到源文件的同级文件(TIFF 或 DNG),再经_import_image自动导入库中,与源图像分组,并继承源图像的用户标签、星级、颜色标签等元数据,因此输出会出现在源图像所在的任何筛选视图或收藏集中。注意:darktable|*内部自动标签会被跳过。


八、添加新的执行提供者(EP)

如果需要接入一个新的 ONNX Runtime 执行提供者,按以下 5 步操作:

  1. 在 src/ai/backend.h 的dt_ai_provider_t枚举中添加枚举值(必须放在DT_AI_PROVIDER_COUNT之前);
  2. dt_ai_providers[]表中添加条目,包含配置字符串、显示名与平台守卫;
  3. 在 src/ai/backend_onnx.c 的_enable_acceleration()中添加case
  4. 在 src/ai/backend_onnx.c 的dt_ai_probe_provider()中添加case
  5. 文件中的_Static_assert会确保表与枚举保持同步(漏改即编译失败)。

九、小结

darktable 的 AI 子系统通过"自包含后端(src/ai)+ 高层任务模块(src/common/ai)+ 注册表/偏好集成(src/common/ai_models.c、src/gui/preferences_ai.c)"三层结构,把 ONNX Runtime 的能力以可扩展、可配置、可下载模型的方式接入摄影工作流。理解本文的 provider 解析、模型 manifest 契约与"UI 只依赖src/common/ai/头文件"的分层纪律,是扩展新任务与新执行提供者的关键。深入各任务细节请继续阅读 AI_Tasks.md,源码级参考可查阅 backend.h、backend_common.c 与 ai_models.h。

【免费下载链接】darktabledarktable is an open source photography workflow application and raw developer项目地址: https://gitcode.com/GitHub_Trending/da/darktable

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

Python批量JSON转TXT:完整方案与工程实践

简介&#xff1a;这是一套Python批量处理JSON转TXT的小工具&#xff0c;面向需要在Python中频繁进行数据格式转换的开发者和数据分析人员&#xff0c;解决将多个JSON文件合并为单一TXT文件时的重复劳动。脚本基于内置json库实现&#xff0c;只需输入文件夹路径即可批量读取多个…

作者头像 李华
网站建设 2026/9/15 13:58:19

UI-TARS 快速指南:把 GUI 模型的输出跑成自动化动作

UI-TARS 快速指南&#xff1a;把 GUI 模型的输出跑成自动化动作 【免费下载链接】UI-TARS Pioneering Automated GUI Interaction with Native Agents 项目地址: https://gitcode.com/GitHub_Trending/ui/UI-TARS 你让视觉模型看一张截图&#xff0c;它回你一行字&#…

作者头像 李华
网站建设 2026/9/15 13:58:04

良品铺子网站规划和建设到底多少钱?域名服务器避坑指南

良品铺子网站规划和建设到底多少钱?域名服务器避坑指南 域名服务器搞不懂,报价单看两眼就头晕,这是很多项目经理在做【良品铺子网站规划和建设】时最头疼的事。别急,今天不聊虚的,直接拆解这笔账。很多人问【良品铺子网站规划和建设】多少钱,其实钱花在哪里,决定了你的网站是“能用”还是“好用”。…

作者头像 李华
网站建设 2026/9/15 13:57:03

文件上传漏洞从攻击到防御:绕过手法、代码审计与加固实践

做安全的这些年&#xff0c;如果说哪个漏洞让我觉得“看似不起眼、实际特别致命”&#xff0c;文件上传漏洞绝对排得上前三名。很多开发同学觉得上传功能不过就是“接收文件、存到服务器”&#xff0c;能有什么风险&#xff1f;可真出了问题&#xff0c;往往就是服务器直接被拿…

作者头像 李华