【免费下载链接】koharu
ML-powered manga translator, written in Rust.
这篇技术指南围绕 Koharu(Rust 编写的 ML 驱动漫画翻译器)中crates/koharu-ml/benches/fixtures/inpaint/目录下的 LaMa 4K 基准测试夹具展开,系统讲解image_4k.jpg与mask_4k.png的来源、许可与哈希校验方式,并深入剖析这些夹具在 LaMa、AOT 两个修复模型基准测试中的实际用法,以及它们背后完整的高分辨率修复推理链路(HD 策略、分块、精度控制)。读完本文,你将掌握 Koharu 内部图像修复基准的复现方法、InpaintRequest全部参数的含义与默认值,以及一套可复用的 4K 级图像修复性能验证方案。
一、夹具是什么:一份"可校验、可复现"的 4K 修复测试数据
基准测试夹具(fixture)是整个性能验证体系的地基——只有输入数据是确定、可追溯的,基准结果才有可比性。Koharu 的inpaint夹具目录包含三个文件:
image_4k.jpg(3840×2074)mask_4k.png(3840×2074)README.md(即本文依据的文档)
1.1 图像来源与许可
根据 夹具说明文档,两份数据都有明确出处:
| 文件 | 来源 | 许可 | 说明 |
|---|---|---|---|
image_4k.jpg | 大都会艺术博物馆(Metropolitan Museum of Art)贡献的狩野元信(Kanō Motonobu)《Landscape》一画,经维基共享资源(Wikimedia Commons)发布的 3840 像素渲染版 | CC0 1.0(公有领域) | 画面为传统山水题材,分辨率恰为 4K 横向规格 |
mask_4k.png | 对enesmsahin/simple-lama-inpainting测试数据中mask_1.png的最近邻(nearest-neighbor)缩放,目标尺寸 3840×2074 | Apache-2.0 | 采用最近邻缩放可保证蒙版边缘的原始像素结构不被插值模糊 |
选择公有领域图像作为基准输入是一个刻意设计:任何开发者都能在完全合法的前提下复制、修改与再分发这份测试数据,从而复现基准结果;而蒙版来自 Apache-2.0 许可的知名 LaMa 修复示例项目测试集,保证蒙版形态与社区主流修复评测保持可比性。
1.2 SHA-256 完整性校验
文档为两份数据分别记录了 SHA-256 摘要,用于在下载、复制或缓存后校验文件完整性:
image_4k.jpg:1b6c0a50f8a4a5101d745bda7ee311abb3f4ee011433c71f83e71a9f718eec7amask_4k.png:53f772430d81b5ded3f0b243641b5595d921c37da3fd8f026036090a98d5bb57
实际使用中可以用如下命令校验(例如在仓库根目录执行):
sha256sum crates/koharu-ml/benches/fixtures/inpaint/image_4k.jpg sha256sum crates/koharu-ml/benches/fixtures/inpaint/mask_4k.png如果摘要不匹配,说明文件在传输或裁剪过程中被改动,基准结果将失去可比性——这正是 README 记录哈希的根本目的。
二、夹具的消费方:两个 4K 基准测试入口
夹具并不孤立存在,它是 lama.rs 与 aot_inpainting.rs 两个 Criterion 基准测试共享的输入。两者都通过CARGO_MANIFEST_DIR定位夹具目录,形成与源码树自洽的路径解析:
let fixtures = PathBuf::from(env!("CARGO_MANIFEST_DIR")) .join("benches") .join("fixtures") .join("inpaint"); let image_path = fixtures.join("image_4k.jpg"); let mask_path = fixtures.join("mask_4k.png"); let image = image::open(&image_path)?; let mask = image::open(&mask_path)?.to_luma8();2.1 LaMa 基准:lama.rs
LaMa 基准完整流程如下:初始化koharu_ml运行时 → 加载 LaMa 模型 → 构造默认InpaintRequest→ 在black_box包裹下反复执行推理,避免编译器优化掉计算:
#[tokio::main] async fn main() -> Result<()> { // ... 夹具加载(见上文) ... koharu_ml::init().await?; let model = LaMa::load(koharu_ml::Device::default()).await?; let config = InpaintRequest::default(); let mut criterion = Criterion::default() .sample_size(10) .warm_up_time(Duration::from_secs(3)) .measurement_time(Duration::from_secs(10)) .configure_from_args(); criterion.bench_function("lama/inference/3840x2074", |bencher| { bencher.iter(|| { let output = model .inference(black_box(&image), black_box(&mask), black_box(&config)) .expect("LaMa inference failed"); black_box(output); }); }); criterion.final_summary(); Ok(()) }值得注意的基准工程细节:sample_size(10)、预热 3 秒、测量 10 秒,这套参数对单次推理耗时较长的高分辨率修复模型是合理的——既避免过少的样本带来噪声,又不至于让测量时间失控。configure_from_args()允许通过命令行覆盖这些参数。
2.2 AOT 基准:aot_inpainting.rs
AOT(Aggregated Context Transformations)修复模型复用同一组夹具,基准函数名为aot_inpainting/inference/3840x2074:
let model = AotInpainting::load(koharu_ml::Device::default()).await?; model.inference(&image, &mask)?; // 首次调用也计入热身后再进入测量 criterion.bench_function("aot_inpainting/inference/3840x2074", |bencher| { bencher.iter(|| { let output = model .inference(black_box(&image), black_box(&mask)) .expect("AOT inpainting inference failed"); black_box(output); }); });2.3 运行基准
在仓库根目录执行:
cargo bench -p koharu-ml --bench lama cargo bench -p koharu-ml --bench aot_inpainting首次运行时会经 koharu-runtime 的模型仓库机制按固定 revision 拉取权重(见下文"模型权重来源"),随后 Criterion 会输出吞吐量、平均耗时等统计结果。
三、LaMa 修复模型的源码级实现
夹具服务于模型,理解模型才能读懂基准的意义。crates/koharu-ml/src/lama/ 目录包含四个文件:mod.rs(门面)、config.rs(生成器与推理配置)、model.rs(FFC 生成器前向移植)、processor.rs(IOPaint 兼容的预处理/裁剪编排/后处理)。
3.1 模型权重来源
lama/mod.rs 通过model_repository!宏固定了权重的仓库与 revision:
crate::model_repository!("mayocream/lama-manga" @ "f91c85b26913b3e83f9877867b4c336da3675238" { WEIGHTS = "lama-manga.safetensors" });mayocream/lama-manga是一个面向漫画场景的 LaMa 权重,f91c85b...是固定的 Git revision,lama-manga.safetensors是文件名。宏本身定义在 crates/koharu-ml/src/lib.rs:每个文件名都被包装为koharu_runtime::HuggingFaceFile::pinned(...),即"固定 revision + 固定文件名"的不可变引用——这是确保可复现性的关键:无论何时何地加载,权重内容都一致。LaMa::load的过程即:解析权重路径 → 按默认 FFC 配置构建生成器 → 载入 safetensors。
3.2InpaintRequest:推理配置参数全解
config.rs 定义了面向调用的推理请求结构,字段及其默认值如下:
| 参数 | 类型 | 默认值 | 含义 |
|---|---|---|---|
hd_strategy | HDStrategy | Crop | 高分辨率处理策略:Original(原图直推)/Resize(缩放)/Crop(裁剪) |
hd_strategy_crop_trigger_size | u32 | 800 | 当图像最长边超过该值且策略为Crop时,才触发分块裁剪 |
hd_strategy_crop_margin | u32 | 128 | 每个裁剪块的四周外扩边距(像素),给模型留出上下文 |
hd_strategy_resize_limit | u32 | 1280 | Resize策略下的最长边上限 |
sd_keep_unmasked_area | bool | true | 是否保留非蒙版区域的原像素(合成时只替换蒙版内像素) |
这套默认值与 IOPaint 生态的约定保持一致。基准测试使用InpaintRequest::default(),即默认走Crop策略、触发阈值 800px——3840px 的输入远超阈值,因此必然进入分块路径,恰好覆盖了最考验性能与内存的"多块裁剪 + 多次推理 + 逐块回贴"场景。
3.3 FFC 生成器配置:Big-LaMa 网络结构
FFCResNetGeneratorConfig对应 Big-LaMa 的生成器结构(源码注释指向 advimman/lama 的big-lama.yaml),默认值如下:
| 参数 | 默认值 | 含义 |
|---|---|---|
input_nc/output_nc | 4/3 | 输入 4 通道(masked RGB + mask),输出 3 通道 RGB |
ngf | 64 | 生成器基础特征数 |
n_downsampling | 3 | 下采样级数 |
n_blocks | 18 | 中间 ResNet 块数量 |
max_features | 1024 | 特征数上限 |
init/downsample/resnet_conv_kwargs | 见下 | 各阶段 FFC 卷积的局部/全局通道比例 |
其中 FFC(Fast Fourier Convolution)各阶段的ratio_gin/ratio_gout(输入/输出中全局分支的通道占比)是关键结构参数:初始卷积与下采样阶段均为0.0(纯局部卷积),而 ResNet 残差块中为0.75——即 75% 的通道走傅里叶全局变换,这是 LaMa 高效重建大范围纹理的核心机制。
3.4 前向计算:从蒙版图像到合成结果
model.rs 的Model::forward完整展示了推理语义:
let inverse_mask = mask.ones_like() - &mask; let masked_image = &image * &inverse_mask; let input = Tensor::cat(&[masked_image, mask.shallow_clone()], 1); let predicted = self.generator.forward(&input); predicted * mask + inverse_mask * image即:蒙版外区域被置零得到"残缺图像",与蒙版本身拼接成 4 通道输入;生成器输出预测后,按predicted * mask + inverse_mask * image合成——蒙版内用预测值、蒙版外用原图,这是 LaMa 推理的标准公式。
FFC 生成器内部值得注意的实现细节(model.rs):
- 每个
FFC_BN_ACT模块把特征分为局部(local)与全局(global)两条分支,分别做 BatchNorm 与 ReLU 后再汇合; - 全局分支的
FourierUnit执行rfftn/irfftn(ortho归一化),把实部与虚部当作通道交给 1×1 卷积学习,再重建复数频谱; - FFT 边界刻意放在 FP32 中计算(
to_kind(Kind::Float)),因为torch.fft不支持 BF16;而可学习的卷积与 BatchNorm 保持模型自身精度——这是 BF16 推理精度与数值稳定性的精细平衡。
3.5 预处理与后处理:IOPaint 兼容编排
processor.rs 承担了与 IOPaint 兼容的编排逻辑,核心步骤:
- 维度校验:图像与蒙版必须同尺寸且非零尺寸,否则直接报错;
- 策略分发:按
hd_strategy进入 Crop / Resize / 原图直推三条路径(详见下文); - 模 8 填充:
pad_img_to_modulo(tensor, 8)用对称反射(symmetric reflection)把宽高填充到 8 的倍数,适配生成器的下采样倍数约束; - 裁剪输出:
narrow切回原始尺寸 →clamp(0, 1) * 255→ 若sd_keep_unmasked_area为真,则用蒙版做 alpha 合成,蒙版外像素完全保留原图; - 张量转图像:
squeeze→permute→ 移到 CPU → 转为RgbImage。
其中对称反射填充在 CPU 与 CUDA 上分别实现:CPU 用索引映射(symmetric_index),CUDA 上用取模与where_self的张量化运算,兼顾正确性与设备效率。
四、高分辨率策略:三种 HD 处理路径的取舍
4K 图像远超出生成器的最佳输入尺寸,直接整图推理既不经济也可能失败,因此HDStrategy提供了三条路径(processor.rs):
4.1 Crop(默认):分块裁剪 + 逐块回贴
当最长边超过hd_strategy_crop_trigger_size(默认 800)时:
boxes_from_mask先从蒙版提取所有前景分量:逐行扫描得到包围盒,再经imageproc::find_contours_with_threshold找出外轮廓(BorderType::Outer且无父轮廓),每个轮廓得到一个[left, top, right, bottom]边界框;- 每个边界框调用
crop_box按hd_strategy_crop_margin(默认 128px)外扩出裁剪区域,并处理越界回补(超出画布时反向平移),保证裁剪块完整覆盖目标; - 每个裁剪块独立执行
pad_forward推理,最后把各块结果按坐标replace回原图。
这种策略的好处是:只在蒙版附近消耗计算,蒙版外区域零推理;多个分离的蒙版区域天然并行、互不干扰,特别适合漫画中文字气泡分散分布的场景。
4.2 Resize:整体缩放 + 回贴
当最长边超过hd_strategy_resize_limit(默认 1280)时:按比例缩放到上限内 → 整图推理 → 缩回原尺寸 → 逐像素把蒙版外(灰度值 < 127)的原图复制回来。适合蒙版覆盖范围极大、分块意义不大的场景,但缩放会损失细节。
4.3 Original:原图直推
不满足上述任何触发条件时,直接把原图送入模型(仍会做模 8 填充)。适用于中小尺寸图像,精度最高。
五、精度策略:BF16 的启用条件
backend.rs 中的set_precision决定了推理精度:只有CUDA 且计算能力 ≥ 80(即 Ampere 及之后架构)才启用 BF16,ROCm 则要求gfx908/gfx90a/gfx942/gfx950或gfx11xx/gfx12xx目标;CPU、Vulkan、Metal 一律回退 FP32。加载权重后也会再次调用set_precision做精度对齐。
这对基准测试有直接影响:在同一台机器上,CUDA 卡是否满足 ≥ 80 的算力门槛,会显著改变 4K 推理的耗时与显存占用,因此解读lama/inference/3840x2074的结果时必须注明硬件与精度状态。
六、从基准到产品:夹具背后的真实业务场景
夹具测的不只是模型,更是 Koharu 漫画翻译流水线的核心环节。koharu-pipeline/src/stages/inpainting.rs 将 LaMa、AOT 与 FLUX.2 Klein、RORem Mixed 一起接入InpaintingModel枚举,其中:
- 跳过逻辑(
skip):若页面已有Cleanup类型的RasterLayer,则整页跳过修复——因为自动清理已提交; - 平填优先(
inpaint_tiled):借鉴 BallonsTranslator 的思路,先对纯色气泡内的文本区域直接取色填充(fill_uniform_regions),把剩余蒙版拆成有界裁剪块再逐块推理,显著减少模型调用次数; - 分块合并:
inpaint_tiles用连通域把蒙版分成小块,小块优先并入相邻块(TILE_SIZE限制),大块单独推理,结果按标签合成; - 调用方式:流水线始终以
InpaintRequest::default()调用model.inference,与基准测试的配置完全一致——这意味着基准测得的就是产品线上真实运行的推理路径。
应用层侧,清理指南 说明:检测阶段产出移除蒙版,修复阶段据此生成清理图层;用户在画布上用Remove笔刷手动画蒙版后,系统立即对该区域执行修复并合并进清理图层。文档同时点明模型选型定位:LaMa 与 AOT 提供直接修复,而FLUX.2 Klein 与 RORem Mixed是可带提示词、资源开销更大的生成式替代方案。
七、延伸:AOT 修复模型的对照
与 LaMa 共用夹具的 AOT 模型(crates/koharu-ml/src/aot_inpainting/)走的是另一套编排:权重固定为mayocream/aot-inpainting(revisioncffe2346ac2b5ebe1f2d61335d602d12cc144c6f,文件model.safetensors);默认inference将最长边限制在 2048(inference_with_max_side(image, mask, 2048)),超过则双线性缩放后推理,输出再缩放回原尺寸并做蒙版外像素回贴(processor.rs)。与 LaMa 的分块策略相比,AOT 采用"整体缩放 + 回贴"路线,二者在相同 4K 夹具上的基准对比恰好体现了两种高分辨率策略的工程取舍。
八、相关资源索引
- 夹具说明:crates/koharu-ml/benches/fixtures/inpaint/README.md
- 夹具数据:
image_4k.jpg、mask_4k.png(同目录) - LaMa 基准:crates/koharu-ml/benches/lama.rs;AOT 基准:crates/koharu-ml/benches/aot_inpainting.rs
- LaMa 实现:crates/koharu-ml/src/lama/mod.rs、config.rs、model.rs、processor.rs
- 流水线接入:crates/koharu-pipeline/src/stages/inpainting.rs
- 应用侧清理指南:packages/docs/en/guides/cleanup.mdx
综上所述,inpaint夹具目录虽小,却是 Koharu 修复链路"来源可溯、哈希可验、基准可比、源码可查"这一工程理念的缩影:公有领域原作保证数据合法性,固定 revision 的权重保证模型一致性,InpaintRequest::default()贯通基准与产品线,最终让 4K 分辨率下的每一次修复推理都有据可依、可复现、可对比。
【免费下载链接】koharu
ML-powered manga translator, written in Rust.
相关推荐
突破分辨率限制:LaMa大掩码图像修复技术原理解析
突破分辨率限制:LaMa大掩码图像修复技术原理解析 1. 图像修复的分辨率困境与LaMa的革新 传统图像修复 Image Inpainting 技术长期面临"分
人工智能计算机视觉深度学习图像处理MMagic 中的 AOT-GAN:基于聚合上下文变换的高分辨率图像修复完整指南
MMagic 中的 AOT GAN:基于聚合上下文变换的高分辨率图像修复完整指南 AOT GAN(Aggregated Contextual Transform
媒体生成计算机视觉深度学习人工智能大模型ANBlurredImageView核心功能详解:掌握模糊动画的3大参数配置
ANBlurredImageView核心功能详解:掌握模糊动画的3大参数配置 ANBlurredImageView是一款专注于为UIImageView提供流畅模
移动开发
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考