Boogu-Image-0.1: Boosting Open-Source Unified Multimodal Understanding and Generation

⚠️ 关于"技术报告":截至本文撰写,Boogu 的正式技术报告仍是 "Technical Report (Coming Soon)",arxiv 上尚无论文。本文据仓库 README + 推理代码做交叉精读——架构结论全部来自代码(repo/boogu/...),性能数字来自 README 的 Boogu Arena 图表。涉及训练细节(数据规模、蒸馏配方、损失函数)的部分,代码未开源,只能复述 README 的声明并明确标注"未公开"。等正式报告出来需要复核。

Boogu-Image-0.1 生成示例:写实人像、国风山水、双语书法文字
Fig. 1 — 官方 teaser。三张挂画分别展示三类核心能力:照片级写实人像(左)、国风水墨/岩彩山水(中)、中文书法文字渲染(右,"星星之火可以燎原")。这恰好对应 README 强调的三个 Highlights:精准摄影、稳定文字渲染、多样化风格。(仓库 assets/boogu-infinity-teaser.png)

1. 出发点 (Motivation)

闭源的统一多模态系统(GPT-Image-2、Nano-Banana-Pro、Seedream 5.0)能同时做高质量文生图、图像编辑、双语文字渲染,且效果惊人。README 的核心观点是:这些系统的强大不来自单个模型,而来自一整套高度统一的系统能力(理解 + 数据 + 训练流程)。

Boogu 想验证一个务实的假设:在算力和数据都远不如闭源的条件下,靠系统性地提升"理解能力 + 数据质量 + 训练流程",能不能把开源生成/编辑模型推到接近闭源? 它声称训练数据规模比某些现有开源模型小约一个数量级,却拿到了有竞争力的结果。

这是一篇工程系统型的模型发布,不是方法创新论文——它的价值在于把"MLLM 做理解前端 + DiT 做生成后端 + DMD 做少步蒸馏"这套现代统一架构,用开源、可跑的代码完整地交付出来。所以本文的精读重心放在架构如何在代码里落地,而非某个新公式。

2. 方法 (Method):从代码反推架构

整个 pipeline 三个部件,CPU offload 顺序 mllm -> transformer -> vae 一句话点明了数据流:

repo/boogu/pipelines/boogu/pipeline_boogu.py:L143-L170 — pipeline 三部件与职责

class BooguImagePipeline(DiffusionPipeline, BooguImageLoraLoaderMixin):
    # the MLLM encodes text instructions and optional reference-image context,
    # ... runtime orchestration around prompt rewriting, classifier-free guidance ...
    model_cpu_offload_seq = "mllm->transformer->vae"
    def __init__(self, mllm: Qwen3VLForConditionalGeneration, ...):

即:Qwen3-VL(MLLM)→ Boogu DiT(transformer)→ FLUX.1 VAE。下面逐个拆。

2.1 文本条件:用 MLLM 当"会推理的编码器"

传统文生图用 CLIP/T5 当文本编码器。Boogu 用一个多模态大模型 Qwen3-VL 当编码器——这是"统一理解+生成"的关键。它把"系统提示 + (可选参考图)+ 用户指令"交错编码,取最后一层隐状态作为送给 DiT 的条件特征:

repo/boogu/pipelines/boogu/pipeline_boogu.py:L1399-L1432 — MLLM 交错编码,取末层隐状态作条件

text_encoder_outputs = self.mllm(
    **vlm_inputs, output_hidden_states=True, return_dict=True
)
all_hidden_states = text_encoder_outputs.hidden_states  # 各层 [B, seq, dim]
# 默认只取最后一层(num_instruction_feat_layers=1),与训练对齐
instruction_feats = all_hidden_states[-1]

为什么这样更强?因为同一个 Qwen3-VL 还身兼指令改写/推理器(rewriter / reasoner):

repo/boogu/pipelines/boogu/pipeline_boogu.py:L194-L213 — 编码器与改写器复用同一个 MLLM

if hasattr(mllm, "lm_head"):
    _rewriter_processor = processor
    _text_rewriter_model = mllm        # 整模型(带 lm_head)当"改写器/推理器"
    mllm = mllm.model                  # 内部 backbone 当"编码器"
...
self.text_instruction_rewriter = _text_rewriter_model

用户写"画只猫",改写器先把它扩写成富含细节的指令(甚至带 chain-of-thought 推理,对应 ELO 图里的 "Turbo-Thinking" 变体),再编码进 DiT。理解能力直接转化为生成质量——这就是 README 说"靠提升理解来提升生成"的落点。编辑任务(TI2I)则把参考图交错进 MLLM 上下文做 in-context 条件,系统提示明确要求"先描述输入图特征,再说明如何按指令修改"(pipeline_boogu.py:L231)。

2.2 生成主干:Lumina-Image-2 谱系的 DiT

DiT 主类 BooguImageTransformer2DModel,结构上是 Lumina-Image-2 的扩展。它有三套 refiner + 双流/单流主干块

repo/boogu/models/transformers/transformer_boogu.py:L858-L966 — 三套 refiner + 双流/单流主干

self.noise_refiner = nn.ModuleList([...num_refiner_layers...])     # 精炼噪声图 token
self.ref_image_refiner = nn.ModuleList([...])                     # 精炼参考图 token(编辑用)
self.context_refiner = nn.ModuleList([...])                        # 精炼 MLLM 文本 token
...
self.layers = list(self.double_stream_layers) + list(self.single_stream_layers)

数据流(见 transformer_boogu.py:L1010-L1080 的 forward):图像 patch 经 x_embedder 线性嵌入 → noise_refiner 先单独精炼图像 token;参考图经 ref_image_patch_embedder + 加 image_index_embedding(区分多张参考图)→ ref_image_refiner 精炼;文本特征经 context_refiner 精炼。三者精炼后,进入双流块(图像流、文本流各自走 QKV 再联合注意力,类 FLUX/MMDiT)和单流块(拼成一条序列做自注意力)。

调制用 AdaLN-Zero(LuminaRMSNormZero,从 timestep 嵌入算出 scale/gate),位置编码用 RoPE(rope.py),注意力是 GQA(KV 头数 < Q 头数)。

repo/boogu/models/transformers/block_lumina2.py:L39-L71 — AdaLN-Zero 风格的 RMSNorm 调制

class LuminaRMSNormZero(nn.Module):
    def forward(self, x, emb=None):
        # emb 来自 timestep,切成 4 份:注意力的 scale/gate + MLP 的 scale/gate
        scale_msa, gate_msa, scale_mlp, gate_mlp = emb.chunk(4, dim=1)
        x = self.norm(x) * (1 + scale_msa[:, None])
        return x, gate_msa, scale_mlp, gate_mlp

⚠️ 维度别被代码默认值骗了transformer_boogu.py:L786-L800 的签名默认 hidden_size=2304, num_layers=26, num_double_stream_layers=2, num_attention_heads=24, num_kv_heads=8, instruction_feat_dim=1024。但 README 标称 10B 参数——2304×26 远不到 10B。这些是占位默认值,真实结构由 checkpoint 里的 transformer/config.json 决定(随权重下载)。所以"26 层 / 2 双流"是代码骨架,不是发布模型的真实层数。

2.3 采样:分辨率自适应的时间步偏移

调度器是 flow-matching Euler,但带分辨率自适应的动态时间偏移(dynamic time-shift)——高分辨率(token 多)时把更多采样步分配到高噪声段:

\[t' = \frac{t}{m - m\,t + t}, \qquad m = \text{lin}(\text{numtokens}),\ \ \text{lin}: 256\mapsto 0.5,\ 4096\mapsto 1.15\]

—— 翻译:把均匀的时间步 $t$ 用一个由「图像 token 数」决定的系数 $m$ 重新拉伸。token 越多(图越大),$m$ 越大(最高 1.15),曲线越把步数往高噪声端推——因为大图细节多,早期去噪需要更多步。这是 SD3/FLUX 同款的"分辨率越大、shift 越大"策略。

repo/boogu/schedulers/scheduling_flow_match_euler_discrete_time_shifting.py:L136-L158 — 分辨率→shift 的线性映射 + v2 偏移

def _get_lin_function(x1=256, y1=0.5, x2=4096, y2=1.15):   # token 数 → shift 系数
    m = (y2 - y1) / (x2 - x1); b = y1 - m * x1
    return lambda x: m * x + b

@staticmethod
def _time_shift_v2(t_np, m):
    return (t_np / (m - m * t_np + t_np)).astype(np.float32)  # t' = t/(m - m t + t)

2.4 Turbo:Decoupled DMD 蒸馏到 4 步、无 CFG

Turbo 变体把 25~50 步蒸馏到 4 步,且 CFG=0(text/image guidance 都=1,empty-instruction guidance=0),用的是 DMD(Distribution Matching Distillation)学生采样路径——README 称之为 "Decoupled DMD"(解耦的 DMD,但具体"解耦"了什么,训练代码未开源,无从在代码里验证)。

少步采样本身在代码里很干净:每步先用速度场预测干净图 \(x_0\),再 renoise 到下一个 sigma:

repo/boogu/pipelines/boogu/pipeline_boogu_turbo.py:L73-L116 — DMD 学生:预测 x0 + renoise

def _predict_dmd_student_step(self, latents, sigma, ...):
    model_pred = self.predict(t=torch.tensor(sigma, ...), ...)     # 速度场
    sigma_expanded = torch.full(..., sigma, ...)
    return latents + (1 - sigma_expanded) * model_pred            # 还原干净 x0

def _renoise_dmd_latents(self, latents, sigma, noise, ...):
    sigma_expanded = torch.full(..., sigma, ...)
    return (1 - sigma_expanded) * noise + sigma_expanded * latents  # 重新加噪到下一 sigma

—— 翻译:约定 sigma=1 是干净图、sigma=0 是纯噪声。已知带噪 latent 和模型预测的速度场,$x_0 = \text{latent} + (1-\sigma)\cdot v$ 得到干净估计;renoise 则按 $(1-\sigma)\cdot\text{noise} + \sigma\cdot x_0$ 把它打回下一个噪声水平。4 步 = predict→renoise 循环 4 次。这是 DMD 类少步学生的标准采样形态(与 oftsr-2024 的一步 flow 蒸馏思路同源)。

DMD 路径明确不走普通调度器、不用 CFG、不支持参考图(pipeline_boogu_turbo.py:L13-L15 注释写明)——它自建 sigma schedule,所以 4 步极快。

3. 结论 (Key findings)

性能数字来自 README 的 Boogu Arena(自建的 LM-Arena 风格人类偏好评测,1K+ persona 生成的 prompt,ELO 打分)。

Boogu Arena ELO 排行榜
Fig. 2 — Boogu Arena ELO 排行榜(橙=Boogu,绿=开源,蓝=闭源)。GPT-Image-2 (1196) 与 Nano-Banana-Pro (1087) 领跑;Boogu-Image-0.1-Turbo-Thinking (1048) 与 Seedream-5.0-Lite 并列,Boogu-Image-0.1-Turbo (≈1025) 紧随,位列开源第一梯队,领先 Qwen-Image-2512、Z-Image-Turbo、Qwen-Image、HiDream 等。(仓库 assets/arena_elo_chart.svg)
Boogu Arena ELO 的 bootstrap 95% 置信区间
Fig. 3 — 同一排名的 bootstrap 95% 置信区间(Overall)。置信区间相互重叠较多,说明中段模型(Boogu / Seedream-Lite / Qwen-2512)之间的差距在统计上并不显著——排名要谨慎解读。(仓库 assets/ci_chart.svg)

4. 实现细节 (Implementation notes)

5. 批判性总结 (Critical assessment)

Strengths

Limitations / open questions

When to use / not use

Further reading

讨论 / Comments

评论托管在本仓库的 GitHub Discussions, 需 GitHub 账号。