ProCreations commited on
Commit
ce6c921
·
verified ·
1 Parent(s): eed53e3

Release calibrated Image 2.1 Turbo NVFP4 transformer, accelerated SM120 runtime, quality evidence and real-time demo

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
.gitattributes CHANGED
@@ -33,3 +33,78 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ comparisons/00.jpg filter=lfs diff=lfs merge=lfs -text
37
+ comparisons/01.jpg filter=lfs diff=lfs merge=lfs -text
38
+ comparisons/02.jpg filter=lfs diff=lfs merge=lfs -text
39
+ comparisons/03.jpg filter=lfs diff=lfs merge=lfs -text
40
+ comparisons/04.jpg filter=lfs diff=lfs merge=lfs -text
41
+ comparisons/05.jpg filter=lfs diff=lfs merge=lfs -text
42
+ comparisons/06.jpg filter=lfs diff=lfs merge=lfs -text
43
+ comparisons/07.jpg filter=lfs diff=lfs merge=lfs -text
44
+ comparisons/08.jpg filter=lfs diff=lfs merge=lfs -text
45
+ comparisons/09.jpg filter=lfs diff=lfs merge=lfs -text
46
+ comparisons/10.jpg filter=lfs diff=lfs merge=lfs -text
47
+ comparisons/11.jpg filter=lfs diff=lfs merge=lfs -text
48
+ comparisons/12.jpg filter=lfs diff=lfs merge=lfs -text
49
+ comparisons/13.jpg filter=lfs diff=lfs merge=lfs -text
50
+ comparisons/14.jpg filter=lfs diff=lfs merge=lfs -text
51
+ comparisons/15.jpg filter=lfs diff=lfs merge=lfs -text
52
+ comparisons/edit-0.jpg filter=lfs diff=lfs merge=lfs -text
53
+ comparisons/edit-1.jpg filter=lfs diff=lfs merge=lfs -text
54
+ demo/image-001.png filter=lfs diff=lfs merge=lfs -text
55
+ demo/image-002.png filter=lfs diff=lfs merge=lfs -text
56
+ demo/image-003.png filter=lfs diff=lfs merge=lfs -text
57
+ demo/image-004.png filter=lfs diff=lfs merge=lfs -text
58
+ demo/image-005.png filter=lfs diff=lfs merge=lfs -text
59
+ demo/image-006.png filter=lfs diff=lfs merge=lfs -text
60
+ demo/image-007.png filter=lfs diff=lfs merge=lfs -text
61
+ demo/image-008.png filter=lfs diff=lfs merge=lfs -text
62
+ demo/image-009.png filter=lfs diff=lfs merge=lfs -text
63
+ demo/image-010.png filter=lfs diff=lfs merge=lfs -text
64
+ demo/image-011.png filter=lfs diff=lfs merge=lfs -text
65
+ demo/image-012.png filter=lfs diff=lfs merge=lfs -text
66
+ demo/image-013.png filter=lfs diff=lfs merge=lfs -text
67
+ demo/image-014.png filter=lfs diff=lfs merge=lfs -text
68
+ demo/image-015.png filter=lfs diff=lfs merge=lfs -text
69
+ demo/image-016.png filter=lfs diff=lfs merge=lfs -text
70
+ demo/image-017.png filter=lfs diff=lfs merge=lfs -text
71
+ demo/image-018.png filter=lfs diff=lfs merge=lfs -text
72
+ demo/image-019.png filter=lfs diff=lfs merge=lfs -text
73
+ demo/image-020.png filter=lfs diff=lfs merge=lfs -text
74
+ demo/image-021.png filter=lfs diff=lfs merge=lfs -text
75
+ demo/image-022.png filter=lfs diff=lfs merge=lfs -text
76
+ demo/image-023.png filter=lfs diff=lfs merge=lfs -text
77
+ demo/image-024.png filter=lfs diff=lfs merge=lfs -text
78
+ demo/image-025.png filter=lfs diff=lfs merge=lfs -text
79
+ demo/image-026.png filter=lfs diff=lfs merge=lfs -text
80
+ demo/image-027.png filter=lfs diff=lfs merge=lfs -text
81
+ demo/image-028.png filter=lfs diff=lfs merge=lfs -text
82
+ demo/image-029.png filter=lfs diff=lfs merge=lfs -text
83
+ demo/image-030.png filter=lfs diff=lfs merge=lfs -text
84
+ demo/image-031.png filter=lfs diff=lfs merge=lfs -text
85
+ demo/initial.png filter=lfs diff=lfs merge=lfs -text
86
+ demo/realtime-30s-nvfp4.mp4 filter=lfs diff=lfs merge=lfs -text
87
+ demo/video-contact-nvfp4.jpg filter=lfs diff=lfs merge=lfs -text
88
+ examples/nvfp4-2048.png filter=lfs diff=lfs merge=lfs -text
89
+ examples/nvfp4-dragon.png filter=lfs diff=lfs merge=lfs -text
90
+ examples/nvfp4-together-rgb.png filter=lfs diff=lfs merge=lfs -text
91
+ examples/ref-dragon-white.png filter=lfs diff=lfs merge=lfs -text
92
+ examples/ref-whale-white.png filter=lfs diff=lfs merge=lfs -text
93
+ samples/00.png filter=lfs diff=lfs merge=lfs -text
94
+ samples/01.png filter=lfs diff=lfs merge=lfs -text
95
+ samples/02.png filter=lfs diff=lfs merge=lfs -text
96
+ samples/03.png filter=lfs diff=lfs merge=lfs -text
97
+ samples/04.png filter=lfs diff=lfs merge=lfs -text
98
+ samples/05.png filter=lfs diff=lfs merge=lfs -text
99
+ samples/06.png filter=lfs diff=lfs merge=lfs -text
100
+ samples/07.png filter=lfs diff=lfs merge=lfs -text
101
+ samples/08.png filter=lfs diff=lfs merge=lfs -text
102
+ samples/09.png filter=lfs diff=lfs merge=lfs -text
103
+ samples/10.png filter=lfs diff=lfs merge=lfs -text
104
+ samples/11.png filter=lfs diff=lfs merge=lfs -text
105
+ samples/12.png filter=lfs diff=lfs merge=lfs -text
106
+ samples/13.png filter=lfs diff=lfs merge=lfs -text
107
+ samples/14.png filter=lfs diff=lfs merge=lfs -text
108
+ samples/15.png filter=lfs diff=lfs merge=lfs -text
109
+ samples/edit-0.png filter=lfs diff=lfs merge=lfs -text
110
+ samples/edit-1.png filter=lfs diff=lfs merge=lfs -text
LICENSE ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Qwen RESEARCH LICENSE AGREEMENT
2
+
3
+ Qwen RESEARCH LICENSE AGREEMENT Release Date: September 20, 2026
4
+
5
+ By clicking to agree or by using or distributing any portion or element of the Qwen Materials, you will be deemed to have recognized and accepted the content of this Agreement, which is effective immediately.
6
+
7
+ 1. Definitions
8
+ a. This Qwen RESEARCH LICENSE AGREEMENT (this "Agreement") shall mean the terms and conditions for use, reproduction, distribution and modification of the Materials as defined by this Agreement.
9
+ b. "We" (or "Us") shall mean Hangzhou Tongyi Laboratory Technology Co., Ltd.
10
+ c. "You" (or "Your") shall mean a natural person or legal entity exercising the rights granted by this Agreement and/or using the Materials for any purpose and in any field of use.
11
+ d. "Third Parties" shall mean individuals or legal entities that are not under common control with us or you.
12
+ e. "Qwen" shall mean the large language models, diffusion models, and software and algorithms, consisting of trained model weights, parameters (including optimizer states), machine-learning model code, inference-enabling code, training-enabling code, fine-tuning enabling code and other elements of the foregoing distributed by us.
13
+ f. "Materials" shall mean, collectively, our proprietary Qwen and Documentation (and any portion thereof) made available under this Agreement.
14
+ g. "Source" form shall mean the preferred form for making modifications, including but not limited to model source code, documentation source, and configuration files.
15
+ h. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
16
+ i. "Non-Commercial" shall mean for research or evaluation purposes only.
17
+
18
+ 2. Grant of Rights
19
+ a. You are granted a non-exclusive, worldwide, non-transferable and royalty-free limited license under our intellectual property or other rights owned by us embodied in the Materials to use, reproduce, distribute, copy, create derivative works of, and make modifications to the Materials FOR NON-COMMERCIAL PURPOSES ONLY.
20
+ b. You shall not use the Materials for any commercial purpose without obtaining a separate commercial license from us. If you wish to use the Materials commercially, you shall request a license from us at model-business@notice.qwencloud.com.
21
+
22
+ 3. Redistribution
23
+ Subject to Section 2 (Grant of Rights), you may distribute copies or make the Materials, or derivative works thereof, available as part of a product or service that contains any of them, with or without modifications, and in Source or Object form, provided that you meet the following conditions:
24
+ a. You shall give any other recipients of the Materials or derivative works a copy of this Agreement;
25
+ b. You shall cause any modified files to carry prominent notices stating that you changed the files;
26
+ c. You shall retain in all copies of the Materials that you distribute the following attribution notices within a "Notice" text file distributed as a part of such copies: "Qwen is licensed under the Qwen RESEARCH LICENSE AGREEMENT, Copyright (c) 2026 Hangzhou Tongyi Laboratory Technology Co., Ltd. All Rights Reserved."; and
27
+ d. You may add your own copyright statement to your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of your modifications, or for any such derivative works as a whole, provided your use, reproduction, and distribution of the work otherwise complies with the terms and conditions of this Agreement.
28
+
29
+ 4. Rules of use
30
+ a. The Materials may be subject to export controls or restrictions in China, the United States or other countries or regions. You shall comply with applicable laws and regulations in your use of the Materials.
31
+ b. If you use the Materials or any outputs or results therefrom to create, train, fine-tune, or improve an AI model that is distributed or made available, you shall prominently display “Built with Qwen” or “Improved using Qwen” in the related product documentation.
32
+ c. You shall not use "Qwen" as the primary name or identifier of any derivative works or products; reasonable descriptive use (e.g., "fine-tuned from Qwen Image") is permitted.
33
+
34
+ 5. Intellectual Property
35
+ a. We retain ownership of all intellectual property rights in and to the Materials and derivatives made by or for us. Conditioned upon compliance with the terms and conditions of this Agreement, with respect to any derivative works and modifications of the Materials that are made by you, you are and will be the owner of such derivative works and modifications.
36
+ b. No trademark license is granted to use the trade names, trademarks, service marks, or product names of us, except as required to fulfill notice requirements under this Agreement or as required for reasonable and customary use in describing and redistributing the Materials.
37
+ c. If you commence a lawsuit or other proceedings (including a cross-claim or counterclaim in a lawsuit) against us or any entity alleging that the Materials or any output therefrom, or any part of the foregoing, infringe any intellectual property or other right owned or licensable by you, then all licenses granted to you under this Agreement shall terminate as of the date such lawsuit or other proceeding is commenced or brought.
38
+
39
+ 6. Disclaimer of Warranty and Limitation of Liability
40
+ a. We are not obligated to support, update, provide training for, or develop any further version of the Qwen Materials or to grant any license thereto.
41
+ b. THE MATERIALS ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY OF ANY KIND INCLUDING WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT, OR FITNESS FOR A PARTICULAR PURPOSE. WE MAKE NO WARRANTY AND ASSUME NO RESPONSIBILITY FOR THE SAFETY OR STABILITY OF THE MATERIALS AND ANY OUTPUT THEREFROM.
42
+ c. IN NO EVENT SHALL WE BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM YOUR USE OR INABILITY TO USE THE MATERIALS OR ANY OUTPUT OF IT, NO MATTER HOW IT’S CAUSED.
43
+ d. You will defend, indemnify and hold harmless us from and against any claim by any third party arising out of or related to your use or distribution of the Materials.
44
+
45
+ 7. Survival and Termination.
46
+ a. The term of this Agreement shall commence upon your acceptance of this Agreement or access to the Materials and will continue in full force and effect until terminated in accordance with the terms and conditions herein.
47
+ b. We may terminate this Agreement if you breach any of the terms or conditions of this Agreement. Upon termination of this Agreement, you must delete and cease use of the Materials. Sections 6 and 8 shall survive the termination of this Agreement.
48
+
49
+ 8. Governing Law and Jurisdiction.
50
+ a. This Agreement and any dispute arising out of or relating to it will be governed by the laws of China, without regard to conflict of law principles, and the UN Convention on Contracts for the International Sale of Goods does not apply to this Agreement.
51
+ b. The People's Courts in Hangzhou City shall have exclusive jurisdiction over any dispute arising out of this Agreement.
52
+
53
+ 9. Other Terms and Conditions.
54
+ a. Any arrangements, understandings, or agreements regarding the Material not stated herein are separate from and independent of the terms and conditions of this Agreement. You shall request a separate license from us, if you use the Materials in ways not expressly agreed to in this Agreement.
55
+ b. We shall not be bound by any additional or different terms or conditions communicated by you unless expressly agreed.
Notice ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ Qwen is licensed under the Qwen RESEARCH LICENSE AGREEMENT, Copyright (c) 2026 Hangzhou Tongyi Laboratory Technology Co., Ltd. All Rights Reserved.
2
+
3
+ Built with Qwen.
4
+ ProCreations modified the Qwen-Image-2.1-Turbo transformer weights through calibrated NVFP4 quantization on 2026-10-09. The custom runtime, acceleration and calibration/evaluation scripts were added by ProCreations. Non-commercial research and evaluation only under the included upstream license.
README.md ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: other
3
+ license_name: qwen-research
4
+ license_link: LICENSE
5
+ base_model: Qwen/Qwen-Image-2.1-Turbo
6
+ base_model_relation: quantized
7
+ pipeline_tag: text-to-image
8
+ library_name: diffusers
9
+ tags:
10
+ - diffusers
11
+ - nvfp4
12
+ - fp4
13
+ - svdquant
14
+ - gptq
15
+ - image-generation
16
+ - image-editing
17
+ - blackwell
18
+ - calibrated
19
+ - turbo
20
+ ---
21
+
22
+ # Image 2.1 Turbo Calibrated NVFP4
23
+
24
+ **Built with Qwen.** An independently calibrated NVFP4 W4A4 quantization (with BF16 rank-128 corrections) of the image transformer from [Qwen-Image-2.1-Turbo](https://huggingface.co/Qwen/Qwen-Image-2.1-Turbo), with an accelerated runtime. It generates **1024 × 1024 images in 0.96 s end to end** on an RTX PRO 6000 Blackwell. Research/evaluation only under the included **Qwen Research License**. This is not an official Qwen release.
25
+
26
+ This repository contains the quantized transformer (4.87 GB), an explicit loader and CLI, the full calibration/evaluation source, paired comparisons against BF16 Turbo, raw benchmark and profiler evidence, and a 30-second real-time demonstration. The BF16 text encoder, VAE, processor and the checkpoint's 8-step schedule load from the pinned upstream revision `d65dbc9a7e8f6b5479e33dee6030eaab2a906509`.
27
+
28
+ ## Default: 7 of 8 steps in NVFP4, step 1 in calibrated FP8
29
+
30
+ By default, **step 1 of the 8-step schedule runs the calibrated FP8 transformer** from [Image-2.1-Turbo-Calibrated-FP8](https://huggingface.co/ProCreations/Image-2.1-Turbo-Calibrated-FP8). That step also fills the prompt/reference KV cache. **Steps 2–8 run NVFP4.** A few-step model fixes its composition early, so this one higher-precision step brings NVFP4 much closer to BF16 (LPIPS 0.123 → 0.086, latent cosine 0.966 → 0.983) at the same speed. FP8's cheaper prefix pass offsets its slower GEMMs. The FP8 transformer (7.26 GB) downloads once from its pinned revision and stays resident, which adds about 7 GB of VRAM. `--fp8-first-steps 0` gives pure NVFP4; `--fp8-first-steps 2` is closer still (LPIPS 0.063–0.071) at about 1.0 s.
31
+
32
+ ## Speed
33
+
34
+ RTX PRO 6000 Blackwell (SM120, 96 GB), batch 1, all 8 saved-schedule steps, CFG 1, prefix KV cache.
35
+
36
+ | Runtime | 1024 × 1024 | 2048 × 2048 |
37
+ |---|---:|---:|
38
+ | BF16 Turbo (upstream Diffusers, eager) | 2.05 s | 11.45 s |
39
+ | NVFP4, eager, pure | 1.31 s | 8.40 s |
40
+ | NVFP4 + FP8 step 1, compiled, BF16 attention | 1.03 s | 6.80 s |
41
+ | Pure NVFP4, compiled + SageAttention2 | 0.96 s | 5.33 s |
42
+ | **Release default** (NVFP4 + FP8 step 1, compiled + SageAttention2) | **0.96 s** | **5.38 s** |
43
+
44
+ CUDA-synchronized end-to-end wall time: prompt encoding, all 8 transformer passes and VAE decode. Excluded: model load (about 4.4 s from local NVMe), first-use compilation in a fresh process (about 11 s at 1024, 15 s at 2048; once per resolution), and PNG writing. Five measured runs at 1024 and three at 2048 (five for the rows measured at both sizes in one process), after one warmup. Release default at 1024: mean 0.960 s, min 0.958 s. Stage breakdown: encoder 16 ms, step 1 (FP8) 138 ms, cached NVFP4 steps 101 ms each, VAE 93 ms. Peak GPU allocation: 33.7 GB (1024) and 42.8 GB (2048) with the FP8 step-1 model resident; 26.4 GB and 35.5 GB for pure NVFP4. Raw numbers: [reports/benchmarks](reports/benchmarks/). With the 2× faster GEMMs, attention is the largest single cost at 2048 (16,384 image tokens).
45
+
46
+ ## Quality against BF16 Turbo
47
+
48
+ 18 held-out cases (16 text-to-image, 2 edits) that were not used for calibration, with matched seeds and resolutions (four at 2048², two non-square, the rest 1024²). Images are composited over white and resized to 512 px for LPIPS (AlexNet) and SSIM. Final latents are compared at full resolution.
49
+
50
+ | Runtime | Mean LPIPS ↓ | Mean SSIM ↑ | Mean PSNR | Latent cosine |
51
+ |---|---:|---:|---:|---:|
52
+ | **Release default** (FP8 step 1 + NVFP4) | **0.086** | **0.915** | **25.1 dB** | **0.9827** |
53
+ | Pure NVFP4, compiled + Sage | 0.123 | 0.887 | 23.5 dB | 0.9660 |
54
+ | Pure NVFP4, eager | 0.134 | 0.878 | 23.1 dB | 0.9612 |
55
+ | *FP8 release, for reference* | *0.055* | *0.942* | *28.6 dB* | *0.9891* |
56
+
57
+ All 18 pairs were reviewed visually, along with all 31 images in the demo video. The English and Chinese titles stay correct, transparent RGBA output and both edits work, and fur, feathers, glass and hands look natural. No artifacts were observed. Outputs are **not** identical to BF16: differences show up as composition, pose or identity changes rather than lost detail. With pure NVFP4, a "young man at a pottery wheel" became a different young man and a gouache harbour got a new layout; the FP8 first step restores both. The largest default-mode pair is a macro beetle (LPIPS 0.24, same subject with a shifted fern). SageAttention measured within run-to-run noise (paired runs 0.084–0.089 with Sage vs 0.082–0.087 without). See [comparisons](comparisons/) (BF16 | release default | pure NVFP4 | FP8 release) and [reports/quality_metrics.json](reports/quality_metrics.json). All trials are in [reports/trials](reports/trials/). Keeping every `attn.to_out.0` in FP8 was tested too, but only improved LPIPS 0.134 → 0.130, so it was not adopted. This is a finite fidelity check, not a human-preference study.
58
+
59
+ ## Precision and runtime
60
+
61
+ * **224 projections** (q/k/v/out and SwiGLU gate/proj/out in all 32 blocks) run as **NVFP4 W4A4**, which works like this:
62
+ * **Weights:** a per-layer SmoothQuant factor is folded into the weights, a BF16 **rank-128** SVD correction is removed from the smoothed weight, and the residual is packed as E2M1 with E4M3 block scales over 16 elements plus an FP32 global scale.
63
+ * **Activations:** smoothed and quantized per call with a **dynamic tensor-wide range**, recomputed every call because static ranges clip rare outliers, plus dynamic per-16 block scales.
64
+ * **GEMM:** native FlashInfer 0.7.1 SM120 CuTe-DSL block-scaled FP4 kernel, with the low-rank BF16 branch fused into the FP32 accumulator epilogue.
65
+
66
+ Conditioning, input/output projections, norms, the text encoder and the VAE stay BF16.
67
+ * **Shared low-rank GEMM:** projections that read the same input (q/k/v, gate/proj) compute their rank-128 down-projections in one concatenated GEMM.
68
+ * **Compiled decode:** cached-prefix blocks run under `torch.compile` (dynamic shapes, emulated BF16 cast boundaries).
69
+ * **Split prefill:** step 1's prompt/reference prefix runs alone and fills the KV cache; the image tokens then take the compiled cached path. Prefix tokens never attend to image tokens, so the attention structure is unchanged. The prefix and the image tokens each get their own dynamic activation range.
70
+ * **VAE:** single-frame decode skips Wan's unused video frame cache (bit-identical) and is compiled: 172 → 93 ms at 1024.
71
+ * **Attention:** `--attention sage` uses [SageAttention2](https://github.com/thu-ml/SageAttention) (INT8 QK, FP8 PV, FP32 accumulation) in the cached passes; `--attention bf16` keeps native BF16 SDPA. The default `auto` uses Sage when installed.
72
+ * Not used: step skipping, feature caching, reduced resolution, distillation or LoRA.
73
+
74
+ Kernel evidence for one 1024² default generation, from the profiler: **1,568 native SM120 block-scaled FP4 GEMM launches** (224 × 7 NVFP4 steps); 448 FP8 GEMMs for step 1 (prefix + target passes); 256 SageAttention `qk_int_sv_f8_attn_kernel` launches. One cached NVFP4 step takes 99 ms of GPU time: FP4 GEMMs 52%, the SageAttention kernel 14%, everything else small fused kernels. See [reports/kernel_evidence.json](reports/kernel_evidence.json).
75
+
76
+ This is a **custom Diffusers/FlashInfer format** that requires the included loader. It is not a drop-in Transformers, ComfyUI, Nunchaku, vLLM or TensorRT checkpoint, and needs a GPU with SM120 block-scaled FP4 (RTX PRO 6000 / RTX 50-series Blackwell; only SM120 was tested). Do not cast the loaded transformer. Tested with Torch 2.14.0+cu130, Diffusers 0.41.0, Transformers 5.17.0, flashinfer-python 0.7.1 and driver 615.71.09 ([environment](reports/environment.json)).
77
+
78
+ ## Calibration
79
+
80
+ * **Trajectories:** 64 deterministic BF16 Turbo trajectories on the checkpoint's 8-step schedule: 56 generations and 8 edits, 15 at 2048², 47 at 1024², and two 16:9/9:16. They cover photographs, portraits, textures, illustration, six languages, typography, transparency and compositions.
81
+ * **Activation rows:** 4 token rows per layer at **every** step, 2,048 rows per layer: 512 fit and 512 disjoint diagnostic rows.
82
+ * **Second moments:** full-token input second moments come from all 3.62 M tokens of the same trajectories.
83
+ * **Search per layer:** five smoothing exponents × three residual-weight rounding methods: plain FlashInfer quantizer, activation-weighted 15-point block-scale search, and **GPTQ** error feedback (natural column order, so block scales stay contiguous; per-group scale search). Every candidate is scored with the actual native W4A4 kernel and dynamic range.
84
+ * **Result:** GPTQ won for all 224 layers. Mean diagnostic output NRMSE is **5.03%** (max 10.7%, mid-block `attn.to_out.0`). At the same smoothing, plain rounding averaged 6.40% and block-scale search 5.97% fit NRMSE. The September Image 2.1 (40-step) NVFP4 release was at 5.80%.
85
+
86
+ Everything is in [calibration_search.json](reports/calibration_search.json), [quantization_summary.json](reports/quantization_summary.json) and [calibration_manifest.json](reports/calibration_manifest.json). This is post-training calibration only.
87
+
88
+ ## Run
89
+
90
+ Linux, Python 3.12, an SM120 Blackwell GPU and a CUDA 13 driver.
91
+
92
+ ```bash
93
+ hf download ProCreations/Image-2.1-Turbo-Calibrated-NVFP4 --local-dir Image-2.1-Turbo-Calibrated-NVFP4
94
+ cd Image-2.1-Turbo-Calibrated-NVFP4
95
+ python -m venv .venv && source .venv/bin/activate
96
+ pip install torch==2.14.0 torchvision==0.29.0 --index-url https://download.pytorch.org/whl/cu130
97
+ pip install -r requirements.txt
98
+ # optional, faster attention (see requirements.txt): SageAttention 2.2.0 built from source
99
+ python generate.py --prompt "A kingfisher above a forest stream, wildlife photography" --width 1024 --height 1024 --output image.png
100
+ ```
101
+
102
+ The first run downloads the step-1 FP8 transformer from `ProCreations/Image-2.1-Turbo-Calibrated-FP8` at its pinned revision. Use `--fp8-quant /path/to/transformer` for a local copy, or `--fp8-first-steps 0` for pure NVFP4 with no FP8 download. The 8-step schedule comes from the checkpoint. Defaults are 2048 × 2048; use `--width/--height` (multiples of 16; upstream presets 2048², 2400×1792, 1792×2400, 2528×1696, 1696×2528, 2752×1536, 1536×2752). `--warmup` reports first-use cost separately. `--prompts-json list.json` serves many prompts from one loaded pipeline; `--cache-prompts` reuses exact encoder outputs for repeated text-only prompts (0.93 s per 1024² image on a cache hit). `--eager` disables acceleration. `--base /path/to/Qwen-Image-2.1-Turbo` uses a local upstream snapshot.
103
+
104
+ Library use: `load_pipeline(base, "transformer")` from `nvfp4_runtime.py`, then `accelerate_pipeline(pipe, attention="sage")` from `acceleration.py`, then optionally `enable_fp8_first_steps(pipe, fp8_dir, 1, accelerate=True, attention="sage")`.
105
+
106
+ ### Transparent PNGs, editing and multiple references
107
+
108
+ ```bash
109
+ python generate.py --prompt "A cute mint-green baby dragon mascot, full body" --transparent --width 1024 --height 1024 --output dragon.png
110
+ python generate.py --image input.png --prompt "Change the jacket to blue, keep everything else" --width 1024 --height 1024 --output edited.png
111
+ python generate.py --image examples/ref-dragon-white.png examples/ref-whale-white.png \
112
+ --prompt "Image 1 shows a mint-green baby dragon. Image 2 shows a blue cartoon whale. Create one new picture with the dragon standing next to the whale, both fully visible." \
113
+ --width 1024 --height 1024 --output together.png
114
+ ```
115
+
116
+ `--transparent` adds a transparency instruction and keeps the native alpha channel; no background removal is applied ([examples/nvfp4-dragon.png](examples/nvfp4-dragon.png), 74% transparent pixels). References keep command-line order. Transparent RGBA references with a short "place X next to Y" prompt lost the second character in BF16 Turbo as well, so this is upstream behaviour. White-background references with an explicit description worked in BF16, FP8 and NVFP4 ([examples/nvfp4-together-rgb.png](examples/nvfp4-together-rgb.png)).
117
+
118
+ ## Real-time video
119
+
120
+ [demo/realtime-30s-nvfp4.mp4](demo/realtime-30s-nvfp4.mp4): 30 s, 1024², 30 fps, image only, release default runtime. One completed warmup image is shown at t = 0; after that, each change happens when an actual generation finishes, with all waits kept at 1× speed. The video shows **31 new images in 30 seconds** (mean 0.963 s each, including the Python loop). Maximum capture lag is 2.2 ms, and every sampled decoded frame matches the logged image (min PSNR 34.6 dB). See [verification](demo/video-verification-nvfp4.json), [timestamps](demo/capture_receipt-nvfp4.json) and the [contact sheet](demo/video-contact-nvfp4.jpg). The prompts are disjoint from calibration and evaluation.
121
+
122
+ ## Reproduce
123
+
124
+ `source/` holds the experiment scripts in run order: `verify_base.py`, `calibrate.py`, `hessians.py`, `quantize_nvfp4.py` (`--shard i/n` workers, then one assembly run; needs `weight_quant.py`, `gptq.py` and `dynamic_scale.py`), `evaluate.py`, `hybrid.py` (step-hybrid trial), `assemble_mixed.py` (FP8 `to_out` trial), `metrics.py`, `speedlab.py`, `benchmark.py`, `video.py`, `verify_video.py`. `common.py` holds the workstation paths. Calibration activations and second moments (about 30 GB) are regenerated locally and are not needed for inference. Unit checks: `test_gptq.py` (the GPTQ packer reproduces the reference FP4 quantizer bit-exactly when H = I, and the native kernel decodes it), `test_vae.py` and `test_split.py`.
125
+
126
+ ## License and modifications
127
+
128
+ The original model is under the [Qwen Research License](LICENSE): non-commercial research and evaluation, subject to its terms. Keep [Notice](Notice) and the license when redistributing. The modified weights carry a modification notice in their safetensors metadata and in `transformer/quantization_config.json`. ProCreations, 2026-10-09.
acceleration.py ADDED
@@ -0,0 +1,242 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Acceleration for Image 2.1 Turbo Calibrated FP8 / NVFP4. Built with Qwen.
2
+
3
+ Defaults keep the checkpoint's full 8-step schedule, calibrated quantized GEMMs with FP32
4
+ accumulation and BF16 attention. No step skipping, feature caching or reduced resolution.
5
+
6
+ * Cached-prefix decode blocks are compiled (dynamic shapes, emulated BF16 cast boundaries).
7
+ * NVFP4 projections that read the same input (q/k/v, gate/proj) compute their BF16 low-rank
8
+ down-projections with one concatenated GEMM instead of three/two (same arithmetic per column).
9
+ * The first (KV-cache prefill) step is split: the prompt/reference prefix runs alone, filling the
10
+ cache, then the target image tokens take the same compiled cached path as later steps. Prefix
11
+ tokens never attend to target tokens (causal_condition), so this is the same computation.
12
+ * The single-image VAE decode skips the unused video frame cache and is compiled (cuDNN autotuned).
13
+ * Optional attention='sage' uses SageAttention2 (INT8 QK, FP8 PV, FP32 accumulation) in the
14
+ cached steps; this is an additional approximation and is off unless requested.
15
+ """
16
+ import math
17
+ import types
18
+ import torch
19
+ from diffusers.models.attention_dispatch import dispatch_attention_fn
20
+ from diffusers.models.modeling_outputs import Transformer2DModelOutput
21
+ from diffusers.models.transformers.transformer_qwenimage21 import (
22
+ QwenImage21AttnProcessor, QwenImage21TransformerBlock, _IMG_TOKENS_PER_SLOT,
23
+ _qwenimage21_prefix_segments, _qwenimage21_prepare_qkv,
24
+ )
25
+
26
+ _ORIGINAL_BLOCK_FORWARD = QwenImage21TransformerBlock.forward
27
+
28
+
29
+ @torch.library.custom_op('image21_turbo::sage_attention', mutates_args=())
30
+ def sage_attention(q: torch.Tensor, k: torch.Tensor, v: torch.Tensor) -> torch.Tensor:
31
+ from sageattention import sageattn_qk_int8_pv_fp8_cuda
32
+ return sageattn_qk_int8_pv_fp8_cuda(q, k, v, tensor_layout='NHD', is_causal=False,
33
+ qk_quant_gran='per_warp', pv_accum_dtype='fp32+fp32')
34
+
35
+
36
+ @sage_attention.register_fake
37
+ def _sage_fake(q, k, v):
38
+ return torch.empty_like(q)
39
+
40
+
41
+ def _real_rope(x, frequencies):
42
+ paired = x.float().unflatten(-1, (-1, 2))
43
+ cosine = frequencies.real[None, :, None, :]
44
+ sine = frequencies.imag[None, :, None, :]
45
+ return torch.stack((
46
+ paired[..., 0] * cosine - paired[..., 1] * sine,
47
+ paired[..., 0] * sine + paired[..., 1] * cosine,
48
+ ), dim=-1).flatten(-2).to(x.dtype)
49
+
50
+
51
+ def _projections(modules, x, shared_down):
52
+ """Apply projections that share input x. NVFP4 layers reuse one concatenated down GEMM."""
53
+ if shared_down is None:
54
+ return [m(x) for m in modules]
55
+ shape = x.shape[:-1]
56
+ flat = x.reshape(-1, x.shape[-1]).contiguous()
57
+ d = flat @ shared_down
58
+ outputs, start = [], 0
59
+ for m in modules:
60
+ r = m.down.shape[1]
61
+ outputs.append(m.forward_given(flat, d[:, start:start + r]).reshape(*shape, m.out_features))
62
+ start += r
63
+ return outputs
64
+
65
+
66
+ class NativeAttentionProcessor(QwenImage21AttnProcessor):
67
+ def __init__(self, attention='bf16'):
68
+ super().__init__()
69
+ self.attention = attention
70
+
71
+ def __call__(self, attn, hidden_states, attention_mask=None, rotary_emb=None,
72
+ layer_cache=None, kv_cache_mode=None, cache_write_slice=None,
73
+ segments=None, key_valid=None):
74
+ if kv_cache_mode == 'prefix':
75
+ return self._prefix(attn, hidden_states, rotary_emb, layer_cache, cache_write_slice, segments, key_valid)
76
+ if kv_cache_mode != 'cached' or attention_mask is not None:
77
+ return super().__call__(attn, hidden_states, attention_mask, rotary_emb,
78
+ layer_cache, kv_cache_mode, cache_write_slice,
79
+ segments, key_valid)
80
+ query, key, value = _projections((attn.to_q, attn.to_k, attn.to_v), hidden_states,
81
+ getattr(attn, '_image21_shared_down', None))
82
+ query = query.unflatten(-1, (attn.heads, -1))
83
+ key = key.unflatten(-1, (attn.heads, -1))
84
+ value = value.unflatten(-1, (attn.heads, -1))
85
+ query = attn.norm_q(query).to(value.dtype)
86
+ key = attn.norm_k(key).to(value.dtype)
87
+ if rotary_emb is not None:
88
+ query = _real_rope(query, rotary_emb)
89
+ key = _real_rope(key, rotary_emb)
90
+ cached_key, cached_value = layer_cache.get()
91
+ key = torch.cat((cached_key, key), dim=1)
92
+ value = torch.cat((cached_value, value), dim=1)
93
+ if self.attention == 'sage':
94
+ output = sage_attention(query.contiguous(), key, value)
95
+ else:
96
+ output = torch.nn.functional.scaled_dot_product_attention(
97
+ query.transpose(1, 2), key.transpose(1, 2), value.transpose(1, 2)
98
+ ).transpose(1, 2)
99
+ return attn.to_out[1](attn.to_out[0](output.flatten(2, 3)))
100
+
101
+
102
+ def _prefix(self, attn, hidden_states, rotary_emb, layer_cache, cache_write_slice, segments, key_valid):
103
+ # Upstream prefill attention for the prefix segments only (writes the prefix K/V cache).
104
+ query, key, value, _ = _qwenimage21_prepare_qkv(attn, hidden_states, rotary_emb, layer_cache, 'extract', cache_write_slice)
105
+ outputs = []
106
+ for start, end, is_text in segments:
107
+ seg_mask = None
108
+ if is_text:
109
+ seg_len = end - start
110
+ seg_mask = torch.cat([
111
+ torch.ones(seg_len, start, dtype=torch.bool, device=query.device),
112
+ torch.tril(torch.ones(seg_len, seg_len, dtype=torch.bool, device=query.device)),
113
+ ], dim=1)[None, None]
114
+ if key_valid is not None:
115
+ seg_key_valid = key_valid[:, None, None, :end]
116
+ seg_mask = seg_key_valid if seg_mask is None else (seg_mask & seg_key_valid)
117
+ outputs.append(dispatch_attention_fn(query[:, start:end], key[:, :end], value[:, :end], attn_mask=seg_mask,
118
+ dropout_p=0.0, backend=None, parallel_config=self._parallel_config))
119
+ hidden_states = torch.cat(outputs, dim=1).flatten(2, 3).type_as(query)
120
+ return attn.to_out[1](attn.to_out[0](hidden_states))
121
+
122
+
123
+ def _split_prefill_forward(self, hidden_states, encoder_hidden_states, timestep, img_shapes, img_mask,
124
+ encoder_hidden_states_mask=None, attention_kwargs=None, kv_cache=None,
125
+ kv_cache_mode=None, return_dict=True):
126
+ if kv_cache_mode != 'extract' or kv_cache is None or attention_kwargs or not self.config.causal_condition:
127
+ return self._image21_original_forward(
128
+ hidden_states=hidden_states, encoder_hidden_states=encoder_hidden_states, timestep=timestep,
129
+ img_shapes=img_shapes, img_mask=img_mask, encoder_hidden_states_mask=encoder_hidden_states_mask,
130
+ attention_kwargs=attention_kwargs, kv_cache=kv_cache, kv_cache_mode=kv_cache_mode, return_dict=return_dict)
131
+ # Same preparation as the upstream forward.
132
+ batch_size = hidden_states.shape[0]
133
+ hidden_states = self.img_in(hidden_states)
134
+ encoder_hidden_states = self.txt_in(encoder_hidden_states)
135
+ repeats = torch.where(img_mask, _IMG_TOKENS_PER_SLOT, 1)[0]
136
+ image_pad_mask = torch.repeat_interleave(img_mask[0], repeats)
137
+ target_tokens = math.prod(img_shapes[0][-1])
138
+ joint = torch.cat([encoder_hidden_states,
139
+ encoder_hidden_states.new_zeros(batch_size, target_tokens // 4, encoder_hidden_states.shape[2])], dim=1)
140
+ joint = joint.repeat_interleave(repeats, dim=1)
141
+ joint[:, image_pad_mask] = hidden_states
142
+ rotary_emb = self.pos_embed(img_shapes[0], image_pad_mask, device=hidden_states.device)
143
+ image_ids, target_token_mask = self.build_token_metadata(image_pad_mask, img_shapes[0])
144
+ timestep = timestep.to(hidden_states.dtype)
145
+ timestep = torch.cat([timestep, timestep.new_zeros(1)], dim=0)
146
+ temb = self.time_text_embed(timestep, hidden_states)
147
+ modulation = self.modulation(temb)
148
+ joint_key_valid = None
149
+ if encoder_hidden_states_mask is not None:
150
+ joint_key_valid = torch.ones(batch_size, image_pad_mask.shape[0], dtype=torch.bool, device=hidden_states.device)
151
+ text_positions = (~image_pad_mask).nonzero(as_tuple=True)[0]
152
+ vlm_text_positions = ~img_mask[0][: encoder_hidden_states_mask.shape[1]]
153
+ joint_key_valid[:, text_positions] = encoder_hidden_states_mask.bool()[:, vlm_text_positions]
154
+ prefix_len = int((~target_token_mask).sum())
155
+ # 1) prefix alone: block-causal prefill attention over the prompt/reference tokens; fills the cache.
156
+ segments = _qwenimage21_prefix_segments(image_ids, prefix_len)
157
+ prefix = joint[:, :prefix_len]
158
+ prefix_valid = None if joint_key_valid is None else joint_key_valid[:, :prefix_len]
159
+ for index, block in enumerate(self.transformer_blocks):
160
+ prefix = block(hidden_states=prefix, modulation=modulation, rotary_emb=rotary_emb[:prefix_len],
161
+ attention_mask=None, target_token_mask=target_token_mask[:prefix_len],
162
+ layer_cache=kv_cache.get_layer(index), kv_cache_mode='prefix',
163
+ cache_write_slice=slice(0, prefix_len), segments=segments, key_valid=prefix_valid)
164
+ # 2) target tokens: identical attention to the joint prefill (all prefix keys + own block), compiled path.
165
+ target = joint[:, prefix_len:]
166
+ target_mask = target_token_mask[prefix_len:]
167
+ attention_mask = None if joint_key_valid is None else joint_key_valid[:, None, None, :]
168
+ for index, block in enumerate(self.transformer_blocks):
169
+ target = block(hidden_states=target, modulation=modulation, rotary_emb=rotary_emb[prefix_len:],
170
+ attention_mask=attention_mask, target_token_mask=target_mask,
171
+ layer_cache=kv_cache.get_layer(index), kv_cache_mode='cached',
172
+ cache_write_slice=None, segments=None, key_valid=None)
173
+ output = self.proj_out(self.norm_out(target, temb, target_mask))
174
+ return (output,) if not return_dict else Transformer2DModelOutput(sample=output)
175
+
176
+
177
+ def _swiglu_forward(self, hidden_states):
178
+ gate, proj = _projections((self.gate_layer, self.proj), hidden_states,
179
+ getattr(self, '_image21_shared_down', None))
180
+ return self.out(self.activation_fn(gate) * proj)
181
+
182
+
183
+ def _decode_block(self, hidden_states, modulation, rotary_emb=None,
184
+ attention_mask=None, target_token_mask=None, layer_cache=None,
185
+ kv_cache_mode=None, cache_write_slice=None, segments=None,
186
+ key_valid=None):
187
+ # Cached decode contains only target image tokens. The final t=0 modulation
188
+ # row belongs to the prefix, which was already evaluated during prefill.
189
+ if kv_cache_mode == 'cached':
190
+ modulation = modulation[:-1]
191
+ target_token_mask = None
192
+ return _ORIGINAL_BLOCK_FORWARD(
193
+ self, hidden_states, modulation, rotary_emb, attention_mask,
194
+ target_token_mask, layer_cache, kv_cache_mode, cache_write_slice,
195
+ segments, key_valid,
196
+ )
197
+
198
+
199
+ def _dispatch_block(self, **kwargs):
200
+ if kwargs.get('kv_cache_mode') == 'cached':
201
+ return self._image21_compiled(**kwargs)
202
+ return _ORIGINAL_BLOCK_FORWARD(self, **kwargs)
203
+
204
+
205
+ def _share_down(owner, modules):
206
+ if all(hasattr(m, 'forward_given') for m in modules):
207
+ owner.register_buffer('_image21_shared_down', torch.cat([m.down for m in modules], dim=1).contiguous(),
208
+ persistent=False)
209
+
210
+
211
+ def accelerate_transformer(transformer, attention='bf16', share_lowrank=True, split_prefill=True):
212
+ if getattr(transformer, '_image21_accelerated', False):
213
+ return transformer
214
+ if split_prefill:
215
+ transformer._image21_original_forward = transformer.forward
216
+ transformer.forward = types.MethodType(_split_prefill_forward, transformer)
217
+ torch._dynamo.config.recompile_limit = max(torch._dynamo.config.recompile_limit, 64)
218
+ for block in transformer.transformer_blocks:
219
+ if share_lowrank:
220
+ _share_down(block.attn, (block.attn.to_q, block.attn.to_k, block.attn.to_v))
221
+ _share_down(block.img_mlp, (block.img_mlp.gate_layer, block.img_mlp.proj))
222
+ block.img_mlp.forward = types.MethodType(_swiglu_forward, block.img_mlp)
223
+ block.attn.set_processor(NativeAttentionProcessor(attention))
224
+ block._image21_compiled = torch.compile(
225
+ types.MethodType(_decode_block, block), fullgraph=True, dynamic=True,
226
+ options={'emulate_precision_casts': True},
227
+ )
228
+ block.forward = types.MethodType(_dispatch_block, block)
229
+ transformer._image21_accelerated = True
230
+ return transformer
231
+
232
+
233
+ def accelerate_pipeline(pipe, attention='bf16', compile_vae=True, share_lowrank=True, split_prefill=True):
234
+ """Enable once after loading. First-use compilation is excluded from warm timings."""
235
+ if getattr(pipe, '_image21_accelerated', False):
236
+ return pipe
237
+ accelerate_transformer(pipe.transformer, attention, share_lowrank, split_prefill)
238
+ torch.backends.cudnn.benchmark = True
239
+ from vae_fast import enable_fast_decode
240
+ enable_fast_decode(pipe.vae, compile=compile_vae)
241
+ pipe._image21_accelerated = True
242
+ return pipe
comparisons/00.jpg ADDED

Git LFS Details

  • SHA256: 9e697433aa15c4d6741cd86385b76c97de3fffeeed17e2e31fac15f850ea6c26
  • Pointer size: 131 Bytes
  • Size of remote file: 278 kB
comparisons/01.jpg ADDED

Git LFS Details

  • SHA256: 1333a0de85d725070660bcf34504d0ce9d15053613982088be8f3b6f960a6219
  • Pointer size: 131 Bytes
  • Size of remote file: 257 kB
comparisons/02.jpg ADDED

Git LFS Details

  • SHA256: 67b3f8c507bead0acf23f5dc73b1afdd765a3f4aab478e386556a299292079e4
  • Pointer size: 131 Bytes
  • Size of remote file: 246 kB
comparisons/03.jpg ADDED

Git LFS Details

  • SHA256: 10aad8deb1dcc4edceaf81e556ee4a774e02b9b0459cf452b345ec6422e0cef2
  • Pointer size: 131 Bytes
  • Size of remote file: 249 kB
comparisons/04.jpg ADDED

Git LFS Details

  • SHA256: d45a2b47396f3286ba574f2268b74eb0c5fa061f94a85955e3a04954a1da7580
  • Pointer size: 131 Bytes
  • Size of remote file: 290 kB
comparisons/05.jpg ADDED

Git LFS Details

  • SHA256: c95af580e54a5b1787524a258f35a5b5dad5b5584675c4441a2f4294790c16ac
  • Pointer size: 131 Bytes
  • Size of remote file: 485 kB
comparisons/06.jpg ADDED

Git LFS Details

  • SHA256: 28d68f2b04080b7fd97b470c3c0b6429bb5567637bbad324f7f487caf22cebea
  • Pointer size: 131 Bytes
  • Size of remote file: 169 kB
comparisons/07.jpg ADDED

Git LFS Details

  • SHA256: c90d1528af3020b5b3deeced8c0c8fe968e94b049f8140897a3062ec9b332c2d
  • Pointer size: 131 Bytes
  • Size of remote file: 179 kB
comparisons/08.jpg ADDED

Git LFS Details

  • SHA256: ea83851278b56c51eead6b21d6e783ba5f2e388a20e81c711e7767139f657b64
  • Pointer size: 131 Bytes
  • Size of remote file: 177 kB
comparisons/09.jpg ADDED

Git LFS Details

  • SHA256: 80a5e864c5e364869f60f05d623dd4a221f027d5cf5bb3fbdd15f149f4cec4e5
  • Pointer size: 131 Bytes
  • Size of remote file: 162 kB
comparisons/10.jpg ADDED

Git LFS Details

  • SHA256: bd9ccebf11d75cd2debbe9f16da8b86786eeb01ad08d45cb182b29a6a17db401
  • Pointer size: 131 Bytes
  • Size of remote file: 102 kB
comparisons/11.jpg ADDED

Git LFS Details

  • SHA256: 312d588ab6c68a9d53987319fbb48801cfb5c7fcc87b0a5f6e25841333a4d94c
  • Pointer size: 131 Bytes
  • Size of remote file: 343 kB
comparisons/12.jpg ADDED

Git LFS Details

  • SHA256: abe2f0e7b2933a3a34919ee8299700ad5df393ef18f4c94cea6357b46dc7e829
  • Pointer size: 131 Bytes
  • Size of remote file: 475 kB
comparisons/13.jpg ADDED

Git LFS Details

  • SHA256: 019f2bcb7787a1b6615ed33b129cca0f9eb7e8c6d23eaa570b8a08df9f8270ff
  • Pointer size: 131 Bytes
  • Size of remote file: 117 kB
comparisons/14.jpg ADDED

Git LFS Details

  • SHA256: 859598d7d972d2f9351f4a230d369d6963af31df9383358bce2df24d96e8a49d
  • Pointer size: 131 Bytes
  • Size of remote file: 257 kB
comparisons/15.jpg ADDED

Git LFS Details

  • SHA256: 6491dd83df17c29b51d382e9c74e738bbcf6da13ce92bc86ddc143347bff81a0
  • Pointer size: 131 Bytes
  • Size of remote file: 330 kB
comparisons/edit-0.jpg ADDED

Git LFS Details

  • SHA256: 179404784a16c88a044503ec1eabcbb7d4fe60565a2c22d0ebd7056ddf51ce46
  • Pointer size: 131 Bytes
  • Size of remote file: 366 kB
comparisons/edit-1.jpg ADDED

Git LFS Details

  • SHA256: 16090fb1cfd575ab9e33e04610ab60d9770b86bb33aff3025a946da14b671a32
  • Pointer size: 131 Bytes
  • Size of remote file: 238 kB
demo/capture_receipt-nvfp4.json ADDED
The diff for this file is too large to render. See raw diff
 
demo/image-001.png ADDED

Git LFS Details

  • SHA256: 707479b3127f3f6007b00875840c41147aa1b1495da07d314977bd540a3c8b6b
  • Pointer size: 132 Bytes
  • Size of remote file: 1.97 MB
demo/image-002.png ADDED

Git LFS Details

  • SHA256: 8ca2cb1aad45142aae77a19fd79cf4429ed3e03ab38394018e2eeb03f340d85b
  • Pointer size: 132 Bytes
  • Size of remote file: 1.82 MB
demo/image-003.png ADDED

Git LFS Details

  • SHA256: ebed0e313355791f4b443544514d00aa901148b164c2df6b12150a0f34dae1a3
  • Pointer size: 131 Bytes
  • Size of remote file: 932 kB
demo/image-004.png ADDED

Git LFS Details

  • SHA256: 6ff3159e8aaa3492f33664bc21a562cbc6af9a054facda56390760198dd7a7b9
  • Pointer size: 132 Bytes
  • Size of remote file: 1.08 MB
demo/image-005.png ADDED

Git LFS Details

  • SHA256: 8141bd6a057019044a1ab6b24d5282df52b3ea357a9bce893f03079fe02ffe3a
  • Pointer size: 132 Bytes
  • Size of remote file: 1.38 MB
demo/image-006.png ADDED

Git LFS Details

  • SHA256: 32625f32c37719e5703ab76f973b36b4f04047064d0dfafa5cc81547675bf920
  • Pointer size: 132 Bytes
  • Size of remote file: 1.51 MB
demo/image-007.png ADDED

Git LFS Details

  • SHA256: 1cbf5f86b383930a41ac326a92f72f41561ba340ef0ad0c50cc304d2c1382161
  • Pointer size: 132 Bytes
  • Size of remote file: 2.09 MB
demo/image-008.png ADDED

Git LFS Details

  • SHA256: f71304be68e71ba5a2f9bb1dac0eae66666b86f2377e0fa07e6d816a5540d21a
  • Pointer size: 132 Bytes
  • Size of remote file: 1.62 MB
demo/image-009.png ADDED

Git LFS Details

  • SHA256: 66cb9460d5be208d3502edc5ed93b22a6540063786132135382d11b4b87d6281
  • Pointer size: 132 Bytes
  • Size of remote file: 1.72 MB
demo/image-010.png ADDED

Git LFS Details

  • SHA256: f3846545e7cc46a02e9ce5e22bc20b0499e37d1b84d0a9f606edbc316b063cc8
  • Pointer size: 131 Bytes
  • Size of remote file: 927 kB
demo/image-011.png ADDED

Git LFS Details

  • SHA256: 5e38d3bad40f85b631035463a1976eead47d69b4723ee42925b26b2caa60b037
  • Pointer size: 132 Bytes
  • Size of remote file: 1.75 MB
demo/image-012.png ADDED

Git LFS Details

  • SHA256: 6cd9ac902e37ab39116b4aabc7273921ed921b57a2e22a203ed4b0039696c5e4
  • Pointer size: 132 Bytes
  • Size of remote file: 1.39 MB
demo/image-013.png ADDED

Git LFS Details

  • SHA256: c53ed6967f0c5e554efa8dd1cead4f121c1148ed4257823ef6648624ba0049e0
  • Pointer size: 132 Bytes
  • Size of remote file: 1.19 MB
demo/image-014.png ADDED

Git LFS Details

  • SHA256: 6ac98b211e9ed0d09568b870a659d74b16b9ca7623d0d29adcf3776f35a88005
  • Pointer size: 132 Bytes
  • Size of remote file: 1.49 MB
demo/image-015.png ADDED

Git LFS Details

  • SHA256: 51ce0d842167e879710a4bae6cc074e1fc55bbde2d424f25af255c1a7b978833
  • Pointer size: 132 Bytes
  • Size of remote file: 1.87 MB
demo/image-016.png ADDED

Git LFS Details

  • SHA256: 86ca3bb9823a5707a041b1bdb2e75e664dd64b743447284befc0fc5dd6e9bfe2
  • Pointer size: 132 Bytes
  • Size of remote file: 1.39 MB
demo/image-017.png ADDED

Git LFS Details

  • SHA256: 8d08d8e8882fd630e3310f2fc237529b1c47a3f4f77110ca2416ed22bfd39592
  • Pointer size: 132 Bytes
  • Size of remote file: 1.29 MB
demo/image-018.png ADDED

Git LFS Details

  • SHA256: ff6ae1e245504815a95b4dadb32a6c8fb2c6774f42842816117fae5b035feac6
  • Pointer size: 132 Bytes
  • Size of remote file: 1.27 MB
demo/image-019.png ADDED

Git LFS Details

  • SHA256: b3ac6c10d97e2475613dae05eef644b3609af9211992fb52149258f1e4908902
  • Pointer size: 132 Bytes
  • Size of remote file: 1.56 MB
demo/image-020.png ADDED

Git LFS Details

  • SHA256: 05d454aa3cc5c03e61d2e61da724970bfab76bb6417d4821f51755fbdac44fc7
  • Pointer size: 132 Bytes
  • Size of remote file: 1.31 MB
demo/image-021.png ADDED

Git LFS Details

  • SHA256: 012d64fdca581bba1c2d8724b086411c6512a4f668c832920032add935bec128
  • Pointer size: 132 Bytes
  • Size of remote file: 1.22 MB
demo/image-022.png ADDED

Git LFS Details

  • SHA256: ea29eea9285d1a9c98d1d16d6e496f1bf39f30be8ffd4f043d77097af6e692b3
  • Pointer size: 132 Bytes
  • Size of remote file: 1.69 MB
demo/image-023.png ADDED

Git LFS Details

  • SHA256: 225084b28e77acceeb8c9df834321bcdd52860f972693554e82d4010abd2aea2
  • Pointer size: 132 Bytes
  • Size of remote file: 1.64 MB
demo/image-024.png ADDED

Git LFS Details

  • SHA256: 6c11511750ef6632cb4700518e064e7a0b184c8c9193ddf507a62caffe64adb6
  • Pointer size: 132 Bytes
  • Size of remote file: 1.63 MB
demo/image-025.png ADDED

Git LFS Details

  • SHA256: 26f0fbf198b4df1a3769c1fe0556b4ade62e5c2de526e146a2af630dcadd32c3
  • Pointer size: 132 Bytes
  • Size of remote file: 2 MB
demo/image-026.png ADDED

Git LFS Details

  • SHA256: 81a31e9b25fe97da87aa0a01871b1c63ffa7bc07620a05dbab0e56a8765ad856
  • Pointer size: 132 Bytes
  • Size of remote file: 1.28 MB