FIG-001
Figure
DiT 模型结构图(kblayout 重绘论文 Fig. 2 left):Noised Latent→Patchify→DiT Block×N→Layer Norm→Linear and Reshape→Noise/Σ;Timestep t 与 Label y 经 Embed 侧列进 Block。
| id | FIG-001 |
|---|---|
| type | figure |
| generator | figures/FIG-001.py |
| generator-commit | 35a3dc3 |
| render-params | {steps: 3000, lr: 0.1, optimizer: adam} |
| svg-hash | sha256:b4302ff046bde75308626f79eb38df1c2e3424a6349554392e03326519dfceb2 |
| depicts | CPT-001, SRC-2212.09748 |
| fidelity | checked |
Content
DiT 模型结构(论文 Fig. 2 left 的 kblayout 重绘):主链 Noised Latent (32×32×4) → Patchify → DiT Block × N → Layer Norm → Linear and Reshape → 双输出 Noise / Σ;侧列 Timestep t 与 Label y → Embed → DiT Block。节点尺寸由文本度量驱动(metric-driven node), pch/em 经 to_body 北缘法向进入 Block。
Provenance
- 生成器:
figures/FIG-001.py(自包含:solve → render → 覆写FIG-001.svg;D19 同置契约)。 - 再生成:
kblayout/.venv/bin/python figures/FIG-001.py(确定性, 重跑 hash 不变)。 - fidelity: checked —— 与论文 Fig. 2 left 视觉核对一致(2026-09-04)。
- 渲染于 commit 35a3dc3(majority clearance 默认 + weight_at 修复后)。
Residual Report
接受渲染(35a3dc3,steps=3000/lr=0.1/adam)的残差分解——fidelity: checked 的归因依据:
loss_final 3.39(\(\lVert d \rVert\) 尺度,不跨版本可比)
| term | n | Σw·e | share | max e |
|---|---|---|---|---|
| rect.axis | 10 | 1.16 | 34.4% | 0.0369 |
| layout.em_col | 1 | 0.99 | 29.4% | 0.9947 |
| line.axis | 9 | 0.82 | 24.1% | 0.0245 |
| rect.side_uniform | 10 | 0.37 | 10.8% | 0.0257 |
| rect.border_angle | 10 | 0.01 | 0.4% | 0.0001 |
| layout.origin_anchor | 1 | 0.01 | 0.3% | 0.0222 |
| point_anchor | 16 | 0.00 | 0.1% | 0.0000 |
| rect.dimensions | 10 | 0.00 | 0.1% | 0.0002 |
| text.rigid | 10 | 0.00 | 0.1% | 0.0002 |
| text.anchor | 10 | 0.00 | 0.1% | 0.0002 |
| line.clearance | 9 | 0.00 | 0.0% | 0.0002 |
| rect.center | 10 | 0.00 | 0.0% | 0.0001 |
| direction_bound | 14 | 0.00 | 0.0% | 0.0001 |
| rect_attach | 2 | 0.00 | 0.0% | 0.0002 |
| layout.main_col | 1 | 0.00 | 0.0% | 0.0002 |
| line.acute | 9 | 0.00 | 0.0% | 0.0000 |
| layout.pch_col | 1 | 0.00 | 0.0% | 0.0000 |
| layout.io_row | 1 | 0.00 | 0.0% | 0.0000 |
| layout.output_row | 1 | 0.00 | 0.0% | 0.0000 |
| layout.flow_progress | 4 | 0.00 | 0.0% | 0.0000 |
| layout.pair_no_overlap | 5 | 0.00 | 0.0% | 0.0000 |
| min_seg_length | 19 | 0.00 | 0.0% | 0.0000 |
solve time 4.9s(3000 steps;engine: kgrad/mojo)
生成器源码(figures/FIG-001.py)
"""FIG-001: DiT architecture, left half (paper Fig. 2 left).
Self-contained generator for knowledge card FIG-001 (SYSTEM.md D19):
solve -> render -> overwrite FIG-001.svg next to this script.
Run: kblayout/.venv/bin/python figures/FIG-001.py
"""
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "kblayout"))
from kblayout.core.figure import Figure
from kblayout.ext import layout
from kblayout.ext.line import edge
from kblayout.ext.rect import rect
from kblayout.ext.text import text_block, measure as text_block_measure
FIGURE = Figure(id="dit-latent")
def node(nid, label, cx, cy, *,
font_size: float = 14.0, gap: float = 10.0):
"""Rect wraps the text by one ring of `gap` (composed, not
hardcoded: the text metric drives the rect size - measure() is
the single source of the font geometry, D8-mu)."""
tw, th = text_block_measure(label, font_size, pad=0.0)
w, h = tw + 2 * gap, th + 2 * gap
r = rect(FIGURE, nid, w, h, cx=cx, cy=cy)
text_block(FIGURE, r, label, pad=0.0)
return r
# ---- main chain (upward); Patchify column is offset LEFT so that
# Patchify and Embed sit side-by-side under the (widened) block and
# BOTH go straight up from their North anchors into its bottom
# side - as in the paper figure ----
n_nz = node("noised_latent", "Noised\nLatent", -45, 0)
n_pch = node("patchify", "Patchify", -45, -110)
n_b1 = node("block_1", "DiT Block\n× N", 0, -230, gap=29.0)
n_norm = node("norm", "Layer Norm", 0, -330)
n_lr = node("linear_reshape", "Linear and\nReshape", 0, -430)
# ---- outputs: two parallel prediction heads ----
n_noise = node("noise", "Noise", -90, -530)
n_sigma = node("sigma", "Σ", 90, -530)
# ---- conditioning side column (t/y below Embed, arrows up, as in
# the paper: both feed the block from its bottom side) ----
n_t = node("timestep", "Timestep t", 60, -20)
n_y = node("label", "Label y", 170, -20)
n_em = node("embed", "Embed", 45, -110)
# ---- edges: main chain ----
# pch->block and em->block use to_body: the contact point on the
# block bottom is NOT declared (it lands wherever the normal entry
# meets the energy); declaring b1.bottom (bottom-mid anchor x=0)
# forced a diagonal seed which axis attraction folded into a
# stair-step zigzag (上-横-上). Free normal contact is the paper
# figure's arrow semantics.
main_chain = [n_nz, n_pch, n_b1, n_norm, n_lr]
# explicit chain edges (no auto-for: pch->norm would cross the block)
edge(FIGURE, n_nz.top, n_pch.bottom, bends=0, U0=(0, -1), U1=(0, -1))
edge(FIGURE, n_pch.top, to_body=n_b1, bends=0, sign=-1.0)
edge(FIGURE, n_b1.top, n_norm.bottom, bends=0, U0=(0, -1), U1=(0, -1))
edge(FIGURE, n_norm.top, n_lr.bottom, bends=0, U0=(0, -1), U1=(0, -1))
# outputs split from Linear and Reshape top
edge(FIGURE, n_lr.top, n_noise.bottom, bends=0, U0=(0, -1), U1=(0, -1))
edge(FIGURE, n_lr.top, n_sigma.bottom, bends=0, U0=(0, -1), U1=(0, -1))
# ---- edges: conditioning column ----
edge(FIGURE, n_t.top, n_em.bottom, bends=0, U0=(0, -1), U1=(0, -1))
edge(FIGURE, n_y.top, n_em.bottom, bends=0, U0=(0, -1), U1=(0, -1))
# ---- explicit layout relations ----
for src, dst in zip(main_chain, main_chain[1:]):
FIGURE.constraints.append(layout.flow_progress(src=src, dst=dst, gap=64.0))
edge(FIGURE, n_em.top, to_body=n_b1, bends=0, sign=-1.0)
FIGURE.constraints.append(
layout.align_x(refs=[n_nz.center, n_pch.center], name="layout.pch_col"))
FIGURE.constraints.append(
layout.align_x(refs=[n_b1.center, n_norm.center, n_lr.center],
name="layout.main_col"))
FIGURE.constraints.append(
layout.align_x(refs=[n_t.center, n_em.center], name="layout.em_col"))
FIGURE.constraints.append(
layout.align_y(refs=[n_t.center, n_y.center], name="layout.io_row"))
FIGURE.constraints.append(
layout.align_y(refs=[n_noise.bottom, n_sigma.bottom],
name="layout.output_row"))
for a, b in [(n_nz, n_y), (n_t, n_y), (n_b1, n_y), (n_lr, n_y),
(n_pch, n_em)]:
FIGURE.constraints.append(layout.pair_no_overlap(a=a, b=b, gap=16.0))
# experiment 2026-09-04: single absolute pin (chain entry) - the
# other boxes are free to drift; only relative terms couple them
FIGURE.constraints.append(
layout.origin_anchor(refs=[n_nz.center]))
if __name__ == "__main__":
from kblayout.kgrad.solver import solve_kgrad as solve
from kblayout.render.svg import render
from kblayout.report import backfill_card, print_report
# latest engine: whole-solve loop in one Mojo call (A5: requires
# KGRAD_MOJO_LIB pointing at kblayout/kgrad-mojo; no silent fallback)
res = solve(FIGURE, steps=3000, lr=0.1, momentum=0.9, backend="mojo")
svg = render(res, FIGURE)
out = Path(__file__).with_suffix(".svg")
out.write_text(svg, encoding="utf-8")
print(f"{out.name}: loss {float(res.loss_final):.2f}")
print_report(res)
print(backfill_card(Path(__file__).with_suffix(".md"), res, svg))
关联(2)
- SRC-2212.09748 Scalable Diffusion Models with Transformers
- CPT-001 Diffusion Transformer (DiT)