RGBA-Image-2.1-Turbo Core AI port: bf16 + int8 DiT, text encoder, VAE x3 (debug locations stripped), host/, tokenizer/, card
Browse files- .gitattributes +13 -0
- LICENSE +55 -0
- NOTICE +55 -0
- README.md +325 -0
- config.json +19 -0
- host/host_contract.md +181 -0
- host/rope_axis0_cos.f32 +3 -0
- host/rope_axis0_sin.f32 +3 -0
- host/rope_axis1_cos.f32 +3 -0
- host/rope_axis1_sin.f32 +3 -0
- host/rope_axis2_cos.f32 +3 -0
- host/rope_axis2_sin.f32 +3 -0
- host/scheduler.json +17 -0
- qi21_encoder_dynL_w16a32_ids_iofp32.aimodel/main.hash +2 -0
- qi21_encoder_dynL_w16a32_ids_iofp32.aimodel/main.mlirb +3 -0
- qi21_encoder_dynL_w16a32_ids_iofp32.aimodel/metadata.json +25 -0
- qi21_vae_1024_fp32.aimodel/main.hash +1 -0
- qi21_vae_1024_fp32.aimodel/main.mlirb +3 -0
- qi21_vae_1024_fp32.aimodel/metadata.json +25 -0
- qi21_vae_256_fp32.aimodel/main.hash +1 -0
- qi21_vae_256_fp32.aimodel/main.mlirb +3 -0
- qi21_vae_256_fp32.aimodel/metadata.json +25 -0
- qi21_vae_512_fp32.aimodel/main.hash +0 -0
- qi21_vae_512_fp32.aimodel/main.mlirb +3 -0
- qi21_vae_512_fp32.aimodel/metadata.json +25 -0
- qi21t_dit_full_bf16_dyn_iofp32.aimodel/main.hash +1 -0
- qi21t_dit_full_bf16_dyn_iofp32.aimodel/main.mlirb +3 -0
- qi21t_dit_full_bf16_dyn_iofp32.aimodel/metadata.json +25 -0
- qi21t_dit_full_int8lin_dyn_iofp32.aimodel/main.hash +2 -0
- qi21t_dit_full_int8lin_dyn_iofp32.aimodel/main.mlirb +3 -0
- qi21t_dit_full_int8lin_dyn_iofp32.aimodel/metadata.json +25 -0
- tokenizer/chat_template.jinja +120 -0
- tokenizer/processor_config.json +63 -0
- tokenizer/tokenizer.json +3 -0
- tokenizer/tokenizer_config.json +30 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,16 @@ 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 |
+
host/rope_axis0_cos.f32 filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
host/rope_axis0_sin.f32 filter=lfs diff=lfs merge=lfs -text
|
| 38 |
+
host/rope_axis1_cos.f32 filter=lfs diff=lfs merge=lfs -text
|
| 39 |
+
host/rope_axis1_sin.f32 filter=lfs diff=lfs merge=lfs -text
|
| 40 |
+
host/rope_axis2_cos.f32 filter=lfs diff=lfs merge=lfs -text
|
| 41 |
+
host/rope_axis2_sin.f32 filter=lfs diff=lfs merge=lfs -text
|
| 42 |
+
qi21_encoder_dynL_w16a32_ids_iofp32.aimodel/main.mlirb filter=lfs diff=lfs merge=lfs -text
|
| 43 |
+
qi21_vae_1024_fp32.aimodel/main.mlirb filter=lfs diff=lfs merge=lfs -text
|
| 44 |
+
qi21_vae_256_fp32.aimodel/main.mlirb filter=lfs diff=lfs merge=lfs -text
|
| 45 |
+
qi21_vae_512_fp32.aimodel/main.mlirb filter=lfs diff=lfs merge=lfs -text
|
| 46 |
+
qi21t_dit_full_bf16_dyn_iofp32.aimodel/main.mlirb filter=lfs diff=lfs merge=lfs -text
|
| 47 |
+
qi21t_dit_full_int8lin_dyn_iofp32.aimodel/main.mlirb filter=lfs diff=lfs merge=lfs -text
|
| 48 |
+
tokenizer/tokenizer.json 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,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Qwen is licensed under the Qwen RESEARCH LICENSE AGREEMENT, Copyright (c) 2026 Hangzhou Tongyi Laboratory Technology Co., Ltd. All Rights Reserved.
|
| 2 |
+
|
| 3 |
+
The model files in this repository were converted and re-authored into Apple Core AI .aimodel graphs
|
| 4 |
+
from the Qwen-Image-2.1-Turbo weights (Qwen/Qwen-Image-2.1-Turbo, revision
|
| 5 |
+
d65dbc9a7e8f6b5479e33dee6030eaab2a906509) and the Qwen-Image-2.1 weights (Qwen/Qwen-Image-2.1,
|
| 6 |
+
revision 790c92633540aa0cb11d9abf19eb46d861714758). They were changed as follows.
|
| 7 |
+
|
| 8 |
+
qi21t_dit_full_bf16_dyn_iofp32.aimodel — the diffusion transformer (from Qwen-Image-2.1-Turbo transformer/)
|
| 9 |
+
- Re-authored in plain PyTorch with the checkpoint's parameter names, then exported as one graph.
|
| 10 |
+
- Block-causal attention is computed as two scaled-dot-product-attention calls per block
|
| 11 |
+
(text tokens attend causally to text; image tokens attend to every token).
|
| 12 |
+
- Rotary position embeddings are applied as real-valued cos/sin pairs that the host supplies.
|
| 13 |
+
- The prefix key/value cache is removed: the text prefix is recomputed at every step.
|
| 14 |
+
- Weights and computation are bfloat16; every graph input and output is float32.
|
| 15 |
+
- Both sequence axes are dynamic (text 8-512 tokens, image 64-4096 tokens). Text-to-image only:
|
| 16 |
+
the graph has no condition-image input.
|
| 17 |
+
- The export-time debug locations (the conversion machine's source file paths) are stripped from
|
| 18 |
+
the graph file; the operations and the weights are untouched.
|
| 19 |
+
|
| 20 |
+
qi21t_dit_full_int8lin_dyn_iofp32.aimodel — the same diffusion transformer, with int8 Linear weights
|
| 21 |
+
- The same graph as above, from the same weights.
|
| 22 |
+
- The 232 Linear weight matrices are stored as int8 (symmetric, -127..127, one bfloat16 scale per
|
| 23 |
+
block of 32 input features) and dequantized to bfloat16 inside the graph. The normalization
|
| 24 |
+
weights and all computation stay bfloat16.
|
| 25 |
+
- The export-time debug locations (the conversion machine's source file paths) are stripped from
|
| 26 |
+
the graph file; the operations and the weights are untouched.
|
| 27 |
+
|
| 28 |
+
qi21_encoder_dynL_w16a32_ids_iofp32.aimodel — the text encoder (from Qwen-Image-2.1 text_encoder/)
|
| 29 |
+
- The text encoder of Qwen-Image-2.1-Turbo is byte-identical to that of Qwen-Image-2.1 (750 of 750
|
| 30 |
+
tensors). The graph is the one published in mlboydaisuke/RGBA-Image-2.1-CoreAI (revision
|
| 31 |
+
a9b5c9493571a8c4087dde0f4a191803feb0fd69), with its export-time debug locations (the conversion
|
| 32 |
+
machine's source file paths) stripped; the operations and the weights are untouched.
|
| 33 |
+
- Only the text path of the Qwen3-VL-8B encoder is kept. The vision tower, the language-model head
|
| 34 |
+
and the final RMSNorm are removed; the output is the residual stream after the last layer.
|
| 35 |
+
- Re-authored in plain PyTorch; the token embedding is inside the graph (int32 token ids in).
|
| 36 |
+
- Weights are stored in bfloat16 and all computation is float32; the output is float32.
|
| 37 |
+
- The sequence axis is dynamic (16-512 tokens).
|
| 38 |
+
|
| 39 |
+
qi21_vae_256_fp32.aimodel, qi21_vae_512_fp32.aimodel, qi21_vae_1024_fp32.aimodel — the VAE (from Qwen-Image-2.1 vae/)
|
| 40 |
+
- The float32 VAE weights of Qwen-Image-2.1. The vae/ of Qwen-Image-2.1-Turbo holds the same
|
| 41 |
+
weights rounded to bfloat16. The graphs are the ones published in
|
| 42 |
+
mlboydaisuke/RGBA-Image-2.1-CoreAI (revision a9b5c9493571a8c4087dde0f4a191803feb0fd69), with
|
| 43 |
+
their export-time debug locations (the conversion machine's source file paths) stripped; the
|
| 44 |
+
operations and the weights are untouched.
|
| 45 |
+
- Decoder only, one frame; the VAE encoder is not included.
|
| 46 |
+
- The latent un-normalisation (latents * std + mean) and the token-to-grid unpacking are inside
|
| 47 |
+
the graph.
|
| 48 |
+
- One graph per output size (256x256, 512x512, 1024x1024), float32.
|
| 49 |
+
|
| 50 |
+
Copied without changes from Qwen-Image-2.1-Turbo: LICENSE; config.json (= transformer/config.json);
|
| 51 |
+
tokenizer/ (= processor/ tokenizer.json, tokenizer_config.json, processor_config.json,
|
| 52 |
+
chat_template.jinja).
|
| 53 |
+
|
| 54 |
+
Added by the conversion: host/ (rotary tables and the sampler constants, computed from the model
|
| 55 |
+
definition and the checkpoint's sample_sigmas, and host_contract.md) and README.md.
|
README.md
ADDED
|
@@ -0,0 +1,325 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: other
|
| 3 |
+
license_name: qwen-research
|
| 4 |
+
license_link: LICENSE
|
| 5 |
+
base_model: Qwen/Qwen-Image-2.1-Turbo
|
| 6 |
+
pipeline_tag: text-to-image
|
| 7 |
+
library_name: coreai
|
| 8 |
+
tags:
|
| 9 |
+
- coreai
|
| 10 |
+
- rgba
|
| 11 |
+
- text-to-image
|
| 12 |
+
- apple-silicon
|
| 13 |
+
---
|
| 14 |
+
|
| 15 |
+
# RGBA-Image-2.1-Turbo — Core AI port of Qwen-Image-2.1-Turbo
|
| 16 |
+
|
| 17 |
+
- **Built with Qwen.**
|
| 18 |
+
- **Non-commercial use only** — Qwen Research License (research or evaluation purposes).
|
| 19 |
+
- **macOS 27 on Apple silicon only.** Six Core AI bundles, 39.97 GB (37.22 GiB) in total; a run loads
|
| 20 |
+
five of them, 32.41 GB with the bf16 DiT or 25.73 GB with the int8 DiT.
|
| 21 |
+
|
| 22 |
+
RGBA-Image-2.1-Turbo is [`Qwen/Qwen-Image-2.1-Turbo`](https://huggingface.co/Qwen/Qwen-Image-2.1-Turbo)
|
| 23 |
+
(revision `d65dbc9`) converted to Core AI `.aimodel` graphs with coreai-torch 0.4.1 and coreai-core
|
| 24 |
+
1.0.0b2. On an Apple M4 Max (macOS 27.0 26A428, measured 2026-10-11) the 7B DiT runs a 1024² step in
|
| 25 |
+
4.72 s, so an 8-step image takes about 38 s of DiT time.
|
| 26 |
+
|
| 27 |
+
A Qwen3-VL-8B text encoder (text path only) conditions a 7B single-stream DiT (32 blocks,
|
| 28 |
+
block-causal attention). A 64-channel VAE decodes to four channels, RGBA. The sampler is the
|
| 29 |
+
checkpoint's own: 8 FlowMatch Euler steps on a fixed sigma grid, no CFG. Ask for a transparent
|
| 30 |
+
background in the prompt and the fourth channel is a real alpha.
|
| 31 |
+
|
| 32 |
+
Sizes: 256², 512² and 1024², square. The DiT and the text encoder have dynamic axes (see Graph
|
| 33 |
+
contracts); the VAE has one graph per size. The upstream 1:1 preset of 2048² needs 16,384 image
|
| 34 |
+
tokens, outside this DiT's 64–4096-token axis.
|
| 35 |
+
|
| 36 |
+
## What changed from RGBA-Image-2.1
|
| 37 |
+
|
| 38 |
+
The graph code and the host code are those of
|
| 39 |
+
[RGBA-Image-2.1](https://huggingface.co/mlboydaisuke/RGBA-Image-2.1-CoreAI). The differences, and why
|
| 40 |
+
the rest is the same:
|
| 41 |
+
|
| 42 |
+
- **Sampler.** 8 steps on the grid the checkpoint carries (`sample_sigmas` in its `model_index.json`:
|
| 43 |
+
1.0 … 0.414568), shift 1.0, no `μ`, no CFG. RGBA-Image-2.1 runs 40 steps on a shifted linspace.
|
| 44 |
+
- **DiT.** Re-exported from the Turbo weights with the same exporter: 297 bf16 tensors with the
|
| 45 |
+
base checkpoint's names, shapes and dtypes. An int8 variant ships beside it.
|
| 46 |
+
- **Text encoder.** The Turbo text encoder is byte-identical to the base one (750 of 750 tensors).
|
| 47 |
+
This repo carries RGBA-Image-2.1's encoder graph. Its export-time debug locations are stripped, so
|
| 48 |
+
the file differs from RGBA-Image-2.1's by that alone.
|
| 49 |
+
- **VAE.** The Turbo `vae/` is the base fp32 VAE rounded to bf16 (238 of 238 tensors). This repo
|
| 50 |
+
carries RGBA-Image-2.1's fp32 VAE graphs. Their export-time debug locations are stripped, so the
|
| 51 |
+
files differ from RGBA-Image-2.1's by that alone. Their decode differs from the Turbo pipeline's by
|
| 52 |
+
the rounding band in Measured.
|
| 53 |
+
|
| 54 |
+
The Turbo DiT is a distilled checkpoint. On the same noise and prompt, the fp32 Turbo pipeline's
|
| 55 |
+
8-step image and the fp32 base pipeline's 40-step image are 21.75 dB (256²) and 23.35 dB (512²)
|
| 56 |
+
apart (white-composited RGB PSNR).
|
| 57 |
+
|
| 58 |
+
## Bundle
|
| 59 |
+
|
| 60 |
+
[🤗 mlboydaisuke/RGBA-Image-2.1-Turbo-CoreAI](https://huggingface.co/mlboydaisuke/RGBA-Image-2.1-Turbo-CoreAI)
|
| 61 |
+
|
| 62 |
+
| file | what it is | size |
|
| 63 |
+
| --- | --- | --- |
|
| 64 |
+
| `qi21t_dit_full_bf16_dyn_iofp32.aimodel` | the DiT: bf16 weights and compute, fp32 inputs and outputs | 14.23 GB (13.25 GiB) |
|
| 65 |
+
| `qi21t_dit_full_int8lin_dyn_iofp32.aimodel` | the same DiT with int8 Linear weights (one bf16 scale per 32 inputs), bf16 compute | 7.56 GB (7.04 GiB) |
|
| 66 |
+
| `qi21_encoder_dynL_w16a32_ids_iofp32.aimodel` | the text encoder: bf16 weights, fp32 compute; token ids in, `embed_tokens` inside | 15.14 GB (14.10 GiB) |
|
| 67 |
+
| `qi21_vae_{256,512,1024}_fp32.aimodel` | the VAE decoder, fp32, one per size | 1.01 GB (0.94 GiB) each |
|
| 68 |
+
| `host/` | per-axis RoPE tables, `scheduler.json` (the 8-step grid), [`host_contract.md`](https://huggingface.co/mlboydaisuke/RGBA-Image-2.1-Turbo-CoreAI/blob/main/host/host_contract.md) | |
|
| 69 |
+
| `tokenizer/` | the source's `processor/` files, unchanged | |
|
| 70 |
+
| `config.json` | the source's `transformer/config.json`, unchanged | |
|
| 71 |
+
| `LICENSE`, `NOTICE` | the Qwen Research License and the change notice | |
|
| 72 |
+
|
| 73 |
+
The two DiT bundles have one interface; a run uses one of them. On every gate below the int8 DiT
|
| 74 |
+
stays inside the bar, at the bf16 DiT's speed (within 0.1 %). Compiled, the bf16 DiT is 26.52 GiB
|
| 75 |
+
and the int8 DiT 20.30 GiB.
|
| 76 |
+
|
| 77 |
+
**Compile before you run.** On macOS 27.0 (26A428) the Python runtime crashes on this DiT unless it
|
| 78 |
+
is compiled ahead of time with `--expect-frequent-reshapes` (step 2 below). A plain ahead-of-time
|
| 79 |
+
compile fails at the initial call (`ANERegion.mm:414 … Code=-19`); so did a just-in-time compile of
|
| 80 |
+
the same graph with the base weights on 2026-09-25. The compiled copies need their own disk:
|
| 81 |
+
26.52 GiB for the bf16 DiT or 20.30 GiB for the int8, and 14.10 GiB for the encoder.
|
| 82 |
+
|
| 83 |
+
## Use it
|
| 84 |
+
|
| 85 |
+
There is no Swift app for this model yet. The Python engine
|
| 86 |
+
[`conversion/qwenimage21/pipeline_engine.py`](https://github.com/john-rocky/coreai-model-zoo/blob/main/conversion/qwenimage21/pipeline_engine.py)
|
| 87 |
+
runs the whole loop on the three bundles: tokenize, encode, 8 DiT steps, decode, write a PNG.
|
| 88 |
+
`--turbo` selects the 8-step grid.
|
| 89 |
+
|
| 90 |
+
```
|
| 91 |
+
# 1. the bundles (the tokenizer is in tokenizer/)
|
| 92 |
+
hf download mlboydaisuke/RGBA-Image-2.1-Turbo-CoreAI --local-dir RGBA-Image-2.1-Turbo-CoreAI
|
| 93 |
+
|
| 94 |
+
# 2. compile for the Mac GPU (once per bundle; the gates used --architecture h16c on an M4 Max)
|
| 95 |
+
cd RGBA-Image-2.1-Turbo-CoreAI
|
| 96 |
+
for m in qi21_encoder_dynL_w16a32_ids_iofp32 qi21t_dit_full_bf16_dyn_iofp32 qi21_vae_256_fp32 qi21_vae_1024_fp32; do
|
| 97 |
+
xcrun coreai-build compile $m.aimodel --output aot/$m --platform macOS --architecture h16c \
|
| 98 |
+
--preferred-compute gpu --expect-frequent-reshapes
|
| 99 |
+
done
|
| 100 |
+
R=$PWD; A=$PWD/aot
|
| 101 |
+
|
| 102 |
+
# 3. generate, from a checkout of the zoo
|
| 103 |
+
# (Python with coreai-core 1.0.0b2, torch, numpy, tokenizers, pillow)
|
| 104 |
+
cd /path/to/coreai-model-zoo/conversion/qwenimage21
|
| 105 |
+
python pipeline_engine.py --turbo \
|
| 106 |
+
--prompt "This is an RGBA image with transparency. A cute cartoon dragon sticker. The image has alpha channel and the background is transparent." \
|
| 107 |
+
--size 1024 --seed 42 --tag dragon \
|
| 108 |
+
--tokenizer-json $R/tokenizer/tokenizer.json \
|
| 109 |
+
--encoder $A/qi21_encoder_dynL_w16a32_ids_iofp32/qi21_encoder_dynL_w16a32_ids_iofp32.h16c.aimodelc \
|
| 110 |
+
--dit $A/qi21t_dit_full_bf16_dyn_iofp32/qi21t_dit_full_bf16_dyn_iofp32.h16c.aimodelc \
|
| 111 |
+
--vae $A/qi21_vae_1024_fp32/qi21_vae_1024_fp32.h16c.aimodelc
|
| 112 |
+
# -> _work/samples/dragon.png (RGBA) and dragon_rgb.png (composited on white)
|
| 113 |
+
```
|
| 114 |
+
|
| 115 |
+
For the int8 DiT, compile `qi21t_dit_full_int8lin_dyn_iofp32` the same way and pass its
|
| 116 |
+
`.aimodelc` as `--dit`. The prompt above is the upstream card's recommended form for transparent
|
| 117 |
+
images: "This is an RGBA image with transparency. {subject}. The image has alpha channel and the
|
| 118 |
+
background is transparent." The noise is `torch.randn` on a CPU generator seeded with `--seed`, the
|
| 119 |
+
same draw the reference pipeline makes with a CPU generator and that seed.
|
| 120 |
+
|
| 121 |
+
To check the port against the fp32 reference, record the reference once and run the engine in
|
| 122 |
+
oracle mode. `capture_oracle.py` runs the diffusers-main pipeline in fp32 on the CPU, 17 s of
|
| 123 |
+
generation at 256² on the M4 Max. It needs the full `Qwen/Qwen-Image-2.1-Turbo` snapshot and a venv
|
| 124 |
+
with diffusers main 85c9fa4 and transformers 5.17.
|
| 125 |
+
|
| 126 |
+
```
|
| 127 |
+
python capture_oracle.py --snapshot <Qwen-Image-2.1-Turbo snapshot dir> --model-id Qwen/Qwen-Image-2.1-Turbo \
|
| 128 |
+
--size 256 --steps 8 --tag turbo256 # -> oracle/turbo256/
|
| 129 |
+
python pipeline_engine.py --turbo --oracle oracle/turbo256 \
|
| 130 |
+
--tokenizer-json $R/tokenizer/tokenizer.json \
|
| 131 |
+
--encoder $A/qi21_encoder_dynL_w16a32_ids_iofp32/qi21_encoder_dynL_w16a32_ids_iofp32.h16c.aimodelc \
|
| 132 |
+
--dit $A/qi21t_dit_full_bf16_dyn_iofp32/qi21t_dit_full_bf16_dyn_iofp32.h16c.aimodelc \
|
| 133 |
+
--vae $A/qi21_vae_256_fp32/qi21_vae_256_fp32.h16c.aimodelc
|
| 134 |
+
# prints the latent corr vs the reference after every step, then the RGBA and white-composited PSNR
|
| 135 |
+
```
|
| 136 |
+
|
| 137 |
+
## Which image model should I use?
|
| 138 |
+
|
| 139 |
+
The zoo's Mac text-to-image models are not ranked; pick by trade-off. The two RGBA-Image models write
|
| 140 |
+
RGBA natively, so they fit images that need an alpha channel.
|
| 141 |
+
|
| 142 |
+
| | params | sampler | time @1024 | precision |
|
| 143 |
+
| --- | --- | --- | --- | --- |
|
| 144 |
+
| **FLUX.2 klein** | 4B | 4 steps, guidance-distilled (no CFG) | ~11 s | fp16 or int8 |
|
| 145 |
+
| **Z-Image-Turbo** | 6B | 8 steps + CFG (16 forwards) | ~70 s | bf16, near-lossless |
|
| 146 |
+
| **GLM-Image** | 16B (9B AR + 7B DiT) | AR prior + 20-step DiT | ~208 s | int8 |
|
| 147 |
+
| **RGBA-Image-2.1** | 7B | 40 steps, no CFG | ~190 s | bf16 |
|
| 148 |
+
| **RGBA-Image-2.1-Turbo** | 7B | 8 steps, distilled, no CFG | ~38 s | bf16 or int8 |
|
| 149 |
+
|
| 150 |
+
Times are the ones each card reports, on an M4 Max. For the two RGBA-Image models they are the DiT
|
| 151 |
+
steps at the warm median per forward: 40 × 4.757 s and 8 × 4.721 s. They leave out the encoder, the
|
| 152 |
+
VAE and loading.
|
| 153 |
+
|
| 154 |
+
## Graph contracts
|
| 155 |
+
|
| 156 |
+
Every graph has one function, `main`, and fp32 inputs and outputs except `input_ids`. Both DiT
|
| 157 |
+
bundles have the DiT row's contract.
|
| 158 |
+
|
| 159 |
+
| graph | inputs | output |
|
| 160 |
+
| --- | --- | --- |
|
| 161 |
+
| encoder | `input_ids [1,Lfull]` int32, `Lfull` 16..512 | `hidden [1,Lfull,4096]`: the last layer's residual stream, before the final norm |
|
| 162 |
+
| DiT | `img_tokens [1,N,64]`, `txt_feats [1,L,4096]`, `timestep [1]`, `txt_cos`/`txt_sin [1,L,64]`, `img_cos`/`img_sin [1,N,64]`; `L` 8..512, `N` 64..4096 | `vel [1,N,64]` |
|
| 163 |
+
| VAE | `latents_packed [1,N,64]`, the sampler's latent unchanged | `image [1,4,S,S]`, RGBA in [-1, 1] |
|
| 164 |
+
|
| 165 |
+
- **Prompt.** One tokenization of the text-to-image chat template around the prompt, no padding.
|
| 166 |
+
The DiT reads `hidden[:, drop_idx:]`. `drop_idx` is the token count of the template's system
|
| 167 |
+
part: 14 with this tokenizer. Compute it; do not hard-code it.
|
| 168 |
+
- **Sequence.** `[text L | image N]`, image tokens in raster order, one token per 16×16 px tile
|
| 169 |
+
(256² → 256 tokens, 512² → 1024, 1024² → 4096). There is no 2×2 latent packing.
|
| 170 |
+
- **RoPE.** Text token `i` sits at `(i, i, i)`. Image token `(y, x)` sits at `(L, y − (h − h//2),
|
| 171 |
+
x − (w − w//2))`. `host/` has the per-axis tables for positions −1024..8191.
|
| 172 |
+
- **Sampler.** The 8 sigmas in `host/scheduler.json`, then `0`. Shift 1.0 leaves them unchanged,
|
| 173 |
+
and there is no `μ` and no terminal stretch, so the grid is the same at every size. The DiT's
|
| 174 |
+
`timestep` input is `timesteps[i] / 1000` in fp32 (σᵢ bit for bit on this grid), and each step is
|
| 175 |
+
`x += (σᵢ₊₁ − σᵢ)·v`.
|
| 176 |
+
- **VAE.** The graph unpacks the tokens and applies `latents·std + mean` itself. Feed it the raw
|
| 177 |
+
sampler latent.
|
| 178 |
+
|
| 179 |
+
The full contract, with the formulas a Swift host needs:
|
| 180 |
+
[`host/host_contract.md`](https://huggingface.co/mlboydaisuke/RGBA-Image-2.1-Turbo-CoreAI/blob/main/host/host_contract.md).
|
| 181 |
+
|
| 182 |
+
## Measured
|
| 183 |
+
|
| 184 |
+
M4 Max (128 GiB), macOS 27.0 (26A428), coreai-core 1.0.0b2, 2026-10-11. Bundles compiled ahead of
|
| 185 |
+
time with `--expect-frequent-reshapes` (`--architecture h16c`), run with
|
| 186 |
+
`SpecializationOptions.default()`. Speed runs held the Mac's measurement window, which holds back
|
| 187 |
+
other sessions' heavy jobs. The same form timed in different windows moved by up to 1.6 %. The
|
| 188 |
+
timings were taken on the bundles before their debug locations were stripped; the published files
|
| 189 |
+
compute the same outputs bit for bit (Gates).
|
| 190 |
+
|
| 191 |
+
**DiT speed** (`bench_dit.py`, text L = 40, bf16 DiT):
|
| 192 |
+
|
| 193 |
+
| size | image tokens | initial call | s/forward (warm median of 5) | 8 steps |
|
| 194 |
+
| --- | --- | --- | --- | --- |
|
| 195 |
+
| 256² | 256 | 2.27 s | 0.341 s | 2.7 s |
|
| 196 |
+
| 512² | 1024 | 1.10 s | 1.097 s | 8.8 s |
|
| 197 |
+
| 1024² | 4096 | 4.72 s | 4.721 s | 37.8 s |
|
| 198 |
+
|
| 199 |
+
The int8 DiT against the bf16 one in the same process (`ab_dit.py`, L = 40, 8 alternating pairs per
|
| 200 |
+
size): 0.3409 / 1.0923 / 4.7808 s per forward against 0.3410 / 1.0926 / 4.7850 s.
|
| 201 |
+
|
| 202 |
+
**One image end to end** (`pipeline_engine.py --turbo`, bf16 DiT, inside the measurement window,
|
| 203 |
+
compile cache already warm):
|
| 204 |
+
|
| 205 |
+
| prompt, size | encoder load / call | DiT load / initial step / 8 steps | VAE load / call | total |
|
| 206 |
+
| --- | --- | --- | --- | --- |
|
| 207 |
+
| dragon sticker, 512² | 17.0 / 0.40 s | 2.0 / 3.20 / 10.9 s | 1.2 / 0.38 s | 32.0 s |
|
| 208 |
+
| dragon sticker, 1024² | 3.4 / 0.37 s | 2.0 / 6.63 / 39.6 s | 0.5 / 1.45 s | 47.3 s |
|
| 209 |
+
| apple, 1024² | 3.5 / 0.36 s | 1.9 / 6.64 / 39.3 s | 0.3 / 1.46 s | 47.0 s |
|
| 210 |
+
|
| 211 |
+
Load times vary between processes on this shared Mac: 1.9–43.3 s for the DiT and 2.5–55.8 s for
|
| 212 |
+
the encoder across the gate runs. The cold load of a new `.aimodelc` adds a compile-cache entry the
|
| 213 |
+
size of the compiled bundle (26 GB for the bf16 DiT, 20 GB for the int8).
|
| 214 |
+
|
| 215 |
+
**Memory.** Peak memory footprint 4.80 GB at 512² and 17.77–18.16 GB at 1024²
|
| 216 |
+
(`/usr/bin/time -l`). Its "maximum resident set size", 58.3 GB with the bf16 DiT and 51.6 GB with
|
| 217 |
+
the int8, counts the mapped weight pages of the encoder and the DiT.
|
| 218 |
+
|
| 219 |
+
**Fidelity** against the fp32 diffusers Turbo pipeline (prompt "a red apple on a wooden table,
|
| 220 |
+
studio lighting", seed 1234, the same noise, 8 steps):
|
| 221 |
+
|
| 222 |
+
| size | bf16 DiT: white-composited RGB PSNR / final latent corr | int8 DiT: the same | alpha max\|Δ\| |
|
| 223 |
+
| --- | --- | --- | --- |
|
| 224 |
+
| 256² | 43.79 dB / 0.999961 | 41.76 dB / 0.999944 | 1/255 |
|
| 225 |
+
| 512² | 42.45 dB / 0.999800 | 49.28 dB / 0.999976 | 1/255 |
|
| 226 |
+
| 1024² | 42.50 dB / 0.999926 | 39.32 dB / 0.999873 | 1/255 |
|
| 227 |
+
|
| 228 |
+
The reference decodes with the Turbo bf16 VAE file and the bundles carry the fp32 weights; the band
|
| 229 |
+
between the two (below) is inside these numbers. With the reference's prompt embeddings in place of
|
| 230 |
+
the encoder bundle, 256² scores 46.57 dB (bf16 DiT) and 42.56 dB (int8 DiT).
|
| 231 |
+
|
| 232 |
+
**The VAE band.** The same final latent decoded with the fp32 weights (these bundles) and with the
|
| 233 |
+
Turbo pipeline's bf16 copy:
|
| 234 |
+
|
| 235 |
+
| size | max\|Δ\| on [-1, 1] | uint8 PSNR | max levels, RGB / alpha | bundle vs a fp32 decode of its own weights |
|
| 236 |
+
| --- | --- | --- | --- | --- |
|
| 237 |
+
| 256² | 0.074 | 56.95 dB | 10 / 1 | max\|Δ\| 3.0e-5 |
|
| 238 |
+
| 512² | 0.106 | 58.95 dB | 14 / 1 | max\|Δ\| 3.2e-5 |
|
| 239 |
+
| 1024² | 0.105 | 58.15 dB | 13 / 1 | max\|Δ\| 4.2e-5 |
|
| 240 |
+
|
| 241 |
+
**Gates:**
|
| 242 |
+
|
| 243 |
+
- DiT re-authored in plain PyTorch, fp32, with the Turbo weights, teacher-forced on all 8 steps:
|
| 244 |
+
min corr 0.999999999982 at 256² and 0.999999999997 at 512²; 9 of 9 broken variants fail the bar
|
| 245 |
+
(256²).
|
| 246 |
+
- DiT bundles (GPU), teacher-forced against the fp32 reference, 8/8 steps, NaN 0: min corr 0.999971 /
|
| 247 |
+
0.999940 / 0.999977 at 256² / 512² / 1024² (bf16) and 0.999960 / 0.999883 / 0.999965 (int8).
|
| 248 |
+
- Text encoder bundle on the Turbo reference: min per-token corr 0.999999998629, NaN 0. The host
|
| 249 |
+
tokenizer gives the Turbo processor's ids, `drop_idx` 14.
|
| 250 |
+
- VAE bundles against a fp32 decode of their own weights: max|Δ| 3.0e-5 / 3.2e-5 / 4.2e-5, every
|
| 251 |
+
channel corr ≥ 0.99999995.
|
| 252 |
+
- Sampler: sigmas, timesteps and all 8 Euler steps bit-exact at 256², 512² and 1024². RoPE tables
|
| 253 |
+
bit-exact against diffusers main.
|
| 254 |
+
- Transparency: the dragon prompt above, seed 42: alpha min 0 and all four corner pixels 0 at 512²
|
| 255 |
+
(alpha mean 102) and 1024² (alpha mean 82).
|
| 256 |
+
- Stripped bundles reproduce the unstripped outputs bit for bit. The published files have their
|
| 257 |
+
export-time debug locations stripped; against the bundles they were made from, both DiTs (8
|
| 258 |
+
teacher-forced steps at 256²), the encoder, the three VAEs and a 256² image end to end with each DiT
|
| 259 |
+
give identical outputs.
|
| 260 |
+
|
| 261 |
+
**Other forms tried** (s/forward against the shipped bf16 DiT in the same window):
|
| 262 |
+
|
| 263 |
+
| form | result |
|
| 264 |
+
| --- | --- |
|
| 265 |
+
| int8 Linear weights, AOT with `--expect-frequent-reshapes` | compiles in 301 s, passes every gate, −0.02 / −0.02 / −0.09 % at 256² / 512² / 1024²: ships as the second DiT |
|
| 266 |
+
| image axis fixed at N = 4096 | −0.50 % at L = 40, +0.58 % at L = 18: the dynamic graph ships |
|
| 267 |
+
| `--preferred-compute neural-engine` | 0 Neural Engine regions; runs on the GPU, outputs equal bit for bit, +0.01 / 0.00 / +0.72 % |
|
| 268 |
+
| plain AOT, no `--expect-frequent-reshapes` | crashes at the initial call (`ANERegion.mm:414 … Code=-19`), dynamic and fixed image axis alike |
|
| 269 |
+
| text K/V computed once per image | the 32 text tokens between L = 8 and L = 40 cost 1.59 % of a forward at 512² and 0.51 % at 1024² |
|
| 270 |
+
|
| 271 |
+
## Lessons
|
| 272 |
+
|
| 273 |
+
1. **A probe's compile result does not carry to the full graph, either way.** The 2-layer int8 probe
|
| 274 |
+
with random weights fails the `--expect-frequent-reshapes` compile (`Pass failed:
|
| 275 |
+
MPSMemrefAllocFusion`), on 2026-09-25 and again on 2026-10-11. The full 32-layer int8 DiT with the
|
| 276 |
+
Turbo weights compiles in 301 s and passes every gate. On 2026-09-25 it went the other way: the
|
| 277 |
+
probe ran where the full bf16 DiT crashed. Judge compilation on the full graph.
|
| 278 |
+
2. **A sibling checkpoint can carry a bf16 copy of a component.** The Turbo `vae/` is the base fp32
|
| 279 |
+
VAE rounded to bf16, so the fp32 bundles sit 0.074–0.106 from the Turbo pipeline's decode, 7–10×
|
| 280 |
+
the 1e-2 bar. Gate a bundle against a fp32 decode of the weights it holds, and report the rounding
|
| 281 |
+
band beside it. Alpha is near-constant on an opaque image (0.976–1.000), so its correlation drops
|
| 282 |
+
to 0.966–0.991 under that band: report alpha in levels, not correlation.
|
| 283 |
+
3. **Read a dB gap between two DiT forms next to a nudge control.** The 8-step sampler turns a
|
| 284 |
+
1.25e-5 relative change of the prompt embeddings into 29.03 dB (512²) and 32.08 dB (1024²)
|
| 285 |
+
between dragon stickers. The int8 and bf16 stickers are 34.42 and 28.99 dB apart, the same order.
|
| 286 |
+
78–88 % of the pixels whose alpha moves by more than 2 levels lie within 3 px of the silhouette:
|
| 287 |
+
alpha max|Δ| on a sticker (227–255) measures the edge.
|
| 288 |
+
4. **`--preferred-compute neural-engine` can compile to 0 regions without an error.** This DiT
|
| 289 |
+
compiled that way has no Neural Engine region and runs on the GPU, equal bit for bit to the gpu
|
| 290 |
+
compile. Count the `*ANE_region*` entries before timing an ANE form.
|
| 291 |
+
5. **An exported `.aimodel` carries the export machine's paths.** coreai-torch writes every op's
|
| 292 |
+
source location into `main.mlirb`, and `grep -I` skips that binary. coreai-torch's
|
| 293 |
+
`strip_debug_info` removes them without touching the ops or the weights
|
| 294 |
+
([`strip_bundle.py`](https://github.com/john-rocky/coreai-model-zoo/blob/main/conversion/qwenimage21/strip_bundle.py));
|
| 295 |
+
the result is a new asset, so gate it again.
|
| 296 |
+
|
| 297 |
+
The lessons of the base port (the Neural Engine region, the encoder's fp32 compute, the bf16 band):
|
| 298 |
+
[RGBA-Image-2.1](https://github.com/john-rocky/coreai-model-zoo/blob/main/models/rgba-image-2.1/README.md#lessons).
|
| 299 |
+
Port notes, every gate and the dead ends:
|
| 300 |
+
[`knowledge/qwenimage21-port.md`](https://github.com/john-rocky/coreai-model-zoo/blob/main/knowledge/qwenimage21-port.md).
|
| 301 |
+
Scripts: [`conversion/qwenimage21/`](https://github.com/john-rocky/coreai-model-zoo/tree/main/conversion/qwenimage21).
|
| 302 |
+
|
| 303 |
+
## Licence
|
| 304 |
+
|
| 305 |
+
The weights are Qwen Materials under the **Qwen RESEARCH LICENSE AGREEMENT** (release date
|
| 306 |
+
2026-09-20), included unchanged as
|
| 307 |
+
[`LICENSE`](https://huggingface.co/mlboydaisuke/RGBA-Image-2.1-Turbo-CoreAI/blob/main/LICENSE). A
|
| 308 |
+
summary follows; the Agreement is what binds.
|
| 309 |
+
|
| 310 |
+
- **§2, non-commercial only.** You may use, copy, modify and redistribute the Materials for
|
| 311 |
+
research or evaluation purposes only. Commercial use needs a separate licence from Hangzhou
|
| 312 |
+
Tongyi Laboratory Technology Co., Ltd.; §2(b) gives the contact.
|
| 313 |
+
- **§3, redistribution,** under three conditions: every recipient gets a copy of the Agreement
|
| 314 |
+
(`LICENSE`); modified files carry a notice that they were changed (`NOTICE` lists every change);
|
| 315 |
+
and copies keep the attribution text below in a "Notice" file (`NOTICE`, line 1).
|
| 316 |
+
- **§4(b).** An AI model created from the Materials and made available displays "Built with Qwen"
|
| 317 |
+
prominently in its documentation. This card does, at the top.
|
| 318 |
+
- **§4(c).** "Qwen" is not the primary name of a derivative. This port is named
|
| 319 |
+
RGBA-Image-2.1-Turbo; "Core AI port of Qwen-Image-2.1-Turbo" is the descriptive use the Agreement
|
| 320 |
+
permits.
|
| 321 |
+
|
| 322 |
+
[`NOTICE`](https://huggingface.co/mlboydaisuke/RGBA-Image-2.1-Turbo-CoreAI/blob/main/NOTICE) begins
|
| 323 |
+
with the attribution text §3(c) requires:
|
| 324 |
+
|
| 325 |
+
> Qwen is licensed under the Qwen RESEARCH LICENSE AGREEMENT, Copyright (c) 2026 Hangzhou Tongyi Laboratory Technology Co., Ltd. All Rights Reserved.
|
config.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"_class_name": "QwenImage21Transformer2DModel",
|
| 3 |
+
"_diffusers_version": "0.41.0.dev0",
|
| 4 |
+
"attention_head_dim": 128,
|
| 5 |
+
"axes_dims_rope": [
|
| 6 |
+
16,
|
| 7 |
+
56,
|
| 8 |
+
56
|
| 9 |
+
],
|
| 10 |
+
"causal_condition": true,
|
| 11 |
+
"context_in_dim": 4096,
|
| 12 |
+
"eps": 1e-06,
|
| 13 |
+
"in_channels": 64,
|
| 14 |
+
"mlp_ratio": 3,
|
| 15 |
+
"num_attention_heads": 32,
|
| 16 |
+
"num_layers": 32,
|
| 17 |
+
"out_channels": 64,
|
| 18 |
+
"patch_size": 1
|
| 19 |
+
}
|
host/host_contract.md
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Host contract — RGBA-Image-2.1-Turbo (Core AI port of Qwen-Image-2.1-Turbo)
|
| 2 |
+
|
| 3 |
+
Everything a host computes around the three graphs, for text-to-image, batch 1, no CFG.
|
| 4 |
+
The Python reference of every step below is in the zoo's
|
| 5 |
+
[`conversion/qwenimage21/`](https://github.com/john-rocky/coreai-model-zoo/tree/main/conversion/qwenimage21):
|
| 6 |
+
`qi21_tokenize.py` (tokenizer), `qi21_host.py` (RoPE, pack/unpack), `qi21_sched.py` (sampler,
|
| 7 |
+
`schedule_fixed`), `pipeline_engine.py --turbo` (the whole loop on the three bundles). The first three
|
| 8 |
+
match the diffusers-main pipeline (diffusers 85c9fa4, `Qwen/Qwen-Image-2.1-Turbo` @ `d65dbc9`) exactly:
|
| 9 |
+
the same token ids, bit-identical RoPE tables, bit-identical sigmas and Euler steps.
|
| 10 |
+
`pipeline_engine.py` is scored against the pipeline's fp32 images.
|
| 11 |
+
|
| 12 |
+
This port shares its graph code and its text-encoder and VAE graphs with RGBA-Image-2.1 (the files here
|
| 13 |
+
have their export-time debug locations stripped). Only the DiT weights and the sampler differ. Section 6
|
| 14 |
+
is the part that changed.
|
| 15 |
+
|
| 16 |
+
## 1. The graphs
|
| 17 |
+
|
| 18 |
+
Every graph has one function, `main`. All tensors crossing a graph boundary are fp32, except
|
| 19 |
+
`input_ids` (int32).
|
| 20 |
+
|
| 21 |
+
| bundle | inputs | output | axes |
|
| 22 |
+
| --- | --- | --- | --- |
|
| 23 |
+
| `qi21_encoder_dynL_w16a32_ids_iofp32.aimodel` | `input_ids [1,Lfull]` int32 | `hidden [1,Lfull,4096]` | `Lfull` 16..512 |
|
| 24 |
+
| `qi21t_dit_full_bf16_dyn_iofp32.aimodel` | `img_tokens [1,N,64]`, `txt_feats [1,L,4096]`, `timestep [1]`, `txt_cos [1,L,64]`, `txt_sin [1,L,64]`, `img_cos [1,N,64]`, `img_sin [1,N,64]` | `vel [1,N,64]` | `L` 8..512, `N` 64..4096 |
|
| 25 |
+
| `qi21t_dit_full_int8lin_dyn_iofp32.aimodel` | the same as the bf16 DiT | the same | the same |
|
| 26 |
+
| `qi21_vae_{256,512,1024}_fp32.aimodel` | `latents_packed [1,N,64]` | `image [1,4,S,S]` | fixed: `N = (S/16)²` |
|
| 27 |
+
|
| 28 |
+
- Encoder: the Qwen3-VL-8B text stack (36 layers). bf16 weights, fp32 compute. `embed_tokens` is
|
| 29 |
+
inside the graph. The output is the residual stream after the last layer, **before** the final
|
| 30 |
+
RMSNorm. Do not apply a norm on the host.
|
| 31 |
+
- DiT: 32 blocks, fp32 boundary. Two bundles with one interface; use either. `bf16`: bf16 weights
|
| 32 |
+
and compute. `int8lin`: the 232 Linear weights in int8 (symmetric, one bf16 scale per block of
|
| 33 |
+
32), dequantized inside the graph; norms, scales and compute in bf16.
|
| 34 |
+
- VAE: decoder only, fp32. The graph unpacks the tokens and applies `latents * std + mean` itself.
|
| 35 |
+
|
| 36 |
+
## 2. Tokenize
|
| 37 |
+
|
| 38 |
+
Tokenizer: `tokenizer/tokenizer.json` (Qwen2 BPE, byte-level), the Turbo checkpoint's
|
| 39 |
+
`processor/tokenizer.json`. No BOS token. An empty prompt is replaced by a single space `" "`.
|
| 40 |
+
|
| 41 |
+
Template (text-to-image):
|
| 42 |
+
|
| 43 |
+
```
|
| 44 |
+
<|im_start|>system\nComprehend and analyze the provided prompt.<|im_end|>\n<|im_start|>user\n{prompt}<|im_end|>\n<|im_start|>assistant\n
|
| 45 |
+
```
|
| 46 |
+
|
| 47 |
+
`\n` is a newline character. Encode the whole string once, with no padding and no truncation, to get
|
| 48 |
+
`ids` (length `Lfull`).
|
| 49 |
+
|
| 50 |
+
**`drop_idx`** is the number of tokens of the system part alone,
|
| 51 |
+
`<|im_start|>system\nComprehend and analyze the provided prompt.<|im_end|>\n`. Compute it by encoding
|
| 52 |
+
that string. With this tokenizer it is 14:
|
| 53 |
+
`[151644, 8948, 198, 1092, 30782, 408, 323, 23643, 279, 3897, 9934, 13, 151645, 198]`.
|
| 54 |
+
Check that `ids[:drop_idx]` equals those tokens.
|
| 55 |
+
|
| 56 |
+
`Lfull` must be 16..512 (the encoder's axis), and the DiT needs `L = Lfull − drop_idx` in 8..512.
|
| 57 |
+
The template around the empty-prompt substitute `" "` is 23 tokens (`L` = 9).
|
| 58 |
+
|
| 59 |
+
The Turbo `tokenizer.json` differs from the base checkpoint's only in its offset and decoder
|
| 60 |
+
settings (`trim_offsets`, `add_prefix_space`, `use_regex`). Vocabulary, merges and added tokens are
|
| 61 |
+
the same, and both files give the processor's ids on every prompt the port was gated on.
|
| 62 |
+
|
| 63 |
+
## 3. Encode
|
| 64 |
+
|
| 65 |
+
```
|
| 66 |
+
hidden = encoder(input_ids = ids as int32 [1, Lfull]) # [1, Lfull, 4096]
|
| 67 |
+
prompt_embeds = hidden[:, drop_idx : Lfull] # [1, L, 4096], L = Lfull - drop_idx
|
| 68 |
+
```
|
| 69 |
+
|
| 70 |
+
Pass exactly `Lfull` tokens; the axis is dynamic, so no padding is needed. (Attention is causal, so
|
| 71 |
+
pad tokens never reach the first `Lfull` outputs, but a longer input moves the GPU result by about
|
| 72 |
+
4e-6 relative.) Run the encoder once per image.
|
| 73 |
+
|
| 74 |
+
## 4. Sequence layout and RoPE
|
| 75 |
+
|
| 76 |
+
The DiT's sequence is `[text L | image N]`: the `L` prompt tokens, then the image tokens in raster
|
| 77 |
+
order. One image token covers one 16×16 px tile of the output: for an `S×S` image,
|
| 78 |
+
`h = w = S/16` and `N = h·w` (256² → 256 tokens, 512² → 1024, 1024² → 4096). There is no 2×2 packing.
|
| 79 |
+
|
| 80 |
+
Each token has a 3-axis position `(frame, height, width)`:
|
| 81 |
+
|
| 82 |
+
- text token `i` (0-based) → `(i, i, i)`;
|
| 83 |
+
- image token at row `y`, column `x` (0-based, token index `y·w + x`) →
|
| 84 |
+
`(L, y − (h − h//2), x − (w − w//2))`. The grid is centred on zero. For `h = 16`, rows go −8..7.
|
| 85 |
+
|
| 86 |
+
`host/rope_axis{a}_{cos,sin}.f32` hold one row per position −1024..8191: fp32, little-endian,
|
| 87 |
+
row-major `[9216, P_a]` with `P = (8, 28, 28)`. The row for position `p` is `p + 1024`. A token's
|
| 88 |
+
64 values are the three rows concatenated in axis order:
|
| 89 |
+
|
| 90 |
+
```
|
| 91 |
+
cos[token] = axis0_cos[f + 1024] ++ axis1_cos[hpos + 1024] ++ axis2_cos[wpos + 1024] # 8 + 28 + 28
|
| 92 |
+
sin[token] = the same with the _sin tables
|
| 93 |
+
txt_cos, txt_sin = rows of the L text tokens # [1, L, 64]
|
| 94 |
+
img_cos, img_sin = rows of the N image tokens # [1, N, 64]
|
| 95 |
+
```
|
| 96 |
+
|
| 97 |
+
The tables are `torch.polar(1, outer(pos, 1 / 10000^(arange(0, d, 2)/d)))` for axis widths
|
| 98 |
+
`d = 16, 56, 56`, the same numbers as `QwenImage21Rope.freqs` of diffusers main (bit-exact). Axes 1
|
| 99 |
+
and 2 have the same width, so their files are byte-identical. The six files are byte-identical to
|
| 100 |
+
RGBA-Image-2.1's `host/`. The four tensors depend only on `L`, `h` and `w`: build them once per
|
| 101 |
+
image, not per step.
|
| 102 |
+
|
| 103 |
+
## 5. Noise and pack
|
| 104 |
+
|
| 105 |
+
The initial latent is standard normal noise: 64 channels × `h` rows × `w` columns, channel-major.
|
| 106 |
+
The reference pipeline draws it as `randn((1, 1, 64, h, w))` and packs it into DiT tokens:
|
| 107 |
+
|
| 108 |
+
```
|
| 109 |
+
x[0, y·w + x_, c] = z[c, y, x_] # = z.view(1, 64, h·w).transpose(1, 2)
|
| 110 |
+
```
|
| 111 |
+
|
| 112 |
+
Any N(0, 1) noise generates an image. Matching the Python engine for a given seed needs its exact
|
| 113 |
+
draw: `torch.randn((1, 1, 64, h, w), generator=torch.Generator("cpu").manual_seed(seed))`.
|
| 114 |
+
|
| 115 |
+
## 6. Sampler (FlowMatch Euler, a fixed 8-step grid, no CFG)
|
| 116 |
+
|
| 117 |
+
The checkpoint carries its own sigmas: `sample_sigmas` in its `model_index.json`, copied to
|
| 118 |
+
`host/scheduler.json`. The pipeline passes them to the scheduler in place of a linspace and ignores
|
| 119 |
+
`num_inference_steps`. `use_dynamic_shifting` is false, so there is no `mu` and the grid is the same
|
| 120 |
+
at every image size. All arrays are fp32.
|
| 121 |
+
|
| 122 |
+
```
|
| 123 |
+
sigmas = fp32(sample_sigmas) # 1.0, 0.978453, 0.95418, 0.926626, 0.89508, 0.845148, 0.704534, 0.414568
|
| 124 |
+
sigmas = shift·sigmas / (1 + (shift − 1)·sigmas) # shift 1.0: unchanged, bit for bit
|
| 125 |
+
# shift_terminal null: no terminal stretch
|
| 126 |
+
timesteps = sigmas · num_train_timesteps # fp32
|
| 127 |
+
sigmas = sigmas ++ [0] # 9 values
|
| 128 |
+
for i in 0 ..< 8:
|
| 129 |
+
t = timesteps[i] / 1000 # fp32; this is the DiT `timestep` input
|
| 130 |
+
vel = dit(img_tokens = x, txt_feats = prompt_embeds, timestep = [t], txt_cos, txt_sin, img_cos, img_sin)
|
| 131 |
+
x = x + (sigmas[i+1] − sigmas[i]) · vel # fp32
|
| 132 |
+
```
|
| 133 |
+
|
| 134 |
+
On this grid `t` equals `sigmas[i]` bit for bit at all 8 steps; keep `timesteps[i] / 1000` anyway,
|
| 135 |
+
the form the pipeline uses. `qi21_sched.schedule_fixed` reproduces the reference sigmas, timesteps
|
| 136 |
+
and all 8 Euler steps bit-exactly at 256², 512² and 1024².
|
| 137 |
+
|
| 138 |
+
RGBA-Image-2.1 runs 40 steps on a shifted linspace instead (its `host/host_contract.md`, §6). The
|
| 139 |
+
Turbo DiT is a distilled checkpoint, not the base DiT run for fewer steps: on the same noise and
|
| 140 |
+
prompt, the fp32 Turbo pipeline's 8-step image and the fp32 base pipeline's 40-step image are
|
| 141 |
+
21.75 dB (256²) and 23.35 dB (512²) apart (white-composited RGB PSNR).
|
| 142 |
+
|
| 143 |
+
## 7. Decode
|
| 144 |
+
|
| 145 |
+
```
|
| 146 |
+
image = vae_S(latents_packed = x) # x after the last step, [1, N, 64], exactly as the sampler holds it
|
| 147 |
+
rgba8 = round(clip(image · 0.5 + 0.5, 0, 1) · 255) # [1, 4, S, S] -> channels R, G, B, A
|
| 148 |
+
```
|
| 149 |
+
|
| 150 |
+
Feed the sampler's latent unchanged: no unpacking and no `* std + mean` on the host (the graph does
|
| 151 |
+
both). The four channels are what the reference pipeline saves as an RGBA PNG.
|
| 152 |
+
|
| 153 |
+
The VAE bundles hold the base checkpoint's fp32 VAE weights. The Turbo checkpoint's `vae/` is a bf16
|
| 154 |
+
copy of those weights (all 238 tensors are the round-to-nearest-even of the fp32 ones). Decoding the
|
| 155 |
+
same latent, the two sets of weights differ by up to 0.074–0.106 on the [-1, 1] scale: uint8 PSNR
|
| 156 |
+
56.95 / 58.95 / 58.15 dB at 256² / 512² / 1024², at most 10–14 levels on one channel, 1 level on
|
| 157 |
+
alpha. A host that compares against the diffusers Turbo pipeline sees that band; the bundles match a
|
| 158 |
+
fp32 decode with their own weights to max|Δ| 3.0e-5 – 4.2e-5.
|
| 159 |
+
|
| 160 |
+
## 8. Compile before running on the GPU
|
| 161 |
+
|
| 162 |
+
On macOS 27.0 (26A428) the Python runtime crashes on the 32-block DiT when the `.aimodel` is
|
| 163 |
+
compiled just-in-time: the MPSGraph delegate forms a Neural Engine region inside the graph and the
|
| 164 |
+
ANE inference fails (`ANERegion.mm:414 failed assertion … Code=-19`). A plain ahead-of-time compile
|
| 165 |
+
fails the same way, with a dynamic or a static image axis. What runs is an ahead-of-time compile with
|
| 166 |
+
`--expect-frequent-reshapes`, loaded with `SpecializationOptions.default()`:
|
| 167 |
+
|
| 168 |
+
```
|
| 169 |
+
xcrun coreai-build compile qi21t_dit_full_bf16_dyn_iofp32.aimodel \
|
| 170 |
+
--output aot/qi21t_dit_full_bf16_dyn_iofp32 \
|
| 171 |
+
--platform macOS --architecture h16c --preferred-compute gpu --expect-frequent-reshapes
|
| 172 |
+
# -> aot/qi21t_dit_full_bf16_dyn_iofp32/qi21t_dit_full_bf16_dyn_iofp32.h16c.aimodelc
|
| 173 |
+
```
|
| 174 |
+
|
| 175 |
+
Do the same for the encoder and the VAE bundle you use; every gate of this port ran all three this
|
| 176 |
+
way, on an M4 Max with `--architecture h16c` (without `--architecture`, `coreai-build` compiles for
|
| 177 |
+
every supported architecture). On that Mac the bf16 DiT compiles in 107.6 s to 26.52 GiB, the int8 DiT
|
| 178 |
+
in 301 s to 20.30 GiB; the encoder's compiled copy is 14.10 GiB. With
|
| 179 |
+
`--preferred-compute neural-engine` the DiT compiles to 0 Neural Engine regions and runs on the GPU.
|
| 180 |
+
Whether a Swift host using `GraphModel(computeUnits: .gpu)` hits the same Neural Engine region has
|
| 181 |
+
not been tested.
|
host/rope_axis0_cos.f32
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:2a67b7ed9fea4c3f775dea442cf921f6cfa25be5d7da2671a87a01b154af3b5b
|
| 3 |
+
size 294912
|
host/rope_axis0_sin.f32
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:a6da418893c5551a329985da7efbeb20858736f3fb21077239405f9ffb5f578f
|
| 3 |
+
size 294912
|
host/rope_axis1_cos.f32
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:8152a557c6febd21a2baeded29590c6b5bf18c439da5ddbe110c1273379c6ee3
|
| 3 |
+
size 1032192
|
host/rope_axis1_sin.f32
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:a9e468de85274824afd0a30ecf8ca8bb53005ed0d606b656a65703e51c1b21cc
|
| 3 |
+
size 1032192
|
host/rope_axis2_cos.f32
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:8152a557c6febd21a2baeded29590c6b5bf18c439da5ddbe110c1273379c6ee3
|
| 3 |
+
size 1032192
|
host/rope_axis2_sin.f32
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:a9e468de85274824afd0a30ecf8ca8bb53005ed0d606b656a65703e51c1b21cc
|
| 3 |
+
size 1032192
|
host/scheduler.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"sample_sigmas": [
|
| 3 |
+
1.0,
|
| 4 |
+
0.978453,
|
| 5 |
+
0.95418,
|
| 6 |
+
0.926626,
|
| 7 |
+
0.89508,
|
| 8 |
+
0.845148,
|
| 9 |
+
0.704534,
|
| 10 |
+
0.414568
|
| 11 |
+
],
|
| 12 |
+
"shift": 1.0,
|
| 13 |
+
"use_dynamic_shifting": false,
|
| 14 |
+
"shift_terminal": null,
|
| 15 |
+
"num_train_timesteps": 1000,
|
| 16 |
+
"steps": 8
|
| 17 |
+
}
|
qi21_encoder_dynL_w16a32_ids_iofp32.aimodel/main.hash
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
�KͫRrC�l��´�
|
| 2 |
+
xY��X��zp3�����c
|
qi21_encoder_dynL_w16a32_ids_iofp32.aimodel/main.mlirb
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:17a14bcdab527243b56cc1ecc2b4b40a7859cec45892f97a7033f88fb38ba763
|
| 3 |
+
size 15137683256
|
qi21_encoder_dynL_w16a32_ids_iofp32.aimodel/metadata.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"creationDate" : "20260925T065421Z",
|
| 3 |
+
"assetVersion" : "2.0",
|
| 4 |
+
"description" : "Qwen-Image-2.1 text encoder (Qwen3-VL-8B text stack, all 36 layers), bf16 weights, fp32 compute, int32 input_ids -> fp32 hidden (last layer, before the final norm), dynamic L 16..512. Source: Qwen\/Qwen-Image-2.1@790c926.",
|
| 5 |
+
"license" : "qwen-research",
|
| 6 |
+
"producer" : "coreai-core 1.0.0b2",
|
| 7 |
+
"creatorDefinedMetadata" : {
|
| 8 |
+
"strip" : {
|
| 9 |
+
"what" : "the .aimodel re-saved after coreai-torch's strip_debug_info: every op's source location (file, line, call stack) replaced by an unknown location; the ops and the weights are not touched",
|
| 10 |
+
"from_main_mlirb" : {
|
| 11 |
+
"bytes" : 15138226830,
|
| 12 |
+
"sha256" : "d37b8e64763648cb6a32b23a2199b42d0ee93fac2c3899835d8e64d534563243"
|
| 13 |
+
},
|
| 14 |
+
"main_mlirb" : {
|
| 15 |
+
"bytes" : 15137683256,
|
| 16 |
+
"sha256" : "17a14bcdab527243b56cc1ecc2b4b40a7859cec45892f97a7033f88fb38ba763"
|
| 17 |
+
},
|
| 18 |
+
"tool" : "conversion\/qwenimage21\/strip_bundle.py",
|
| 19 |
+
"versions" : {
|
| 20 |
+
"coreai-torch" : "0.4.1",
|
| 21 |
+
"coreai-core" : "1.0.0b2"
|
| 22 |
+
}
|
| 23 |
+
}
|
| 24 |
+
}
|
| 25 |
+
}
|
qi21_vae_1024_fp32.aimodel/main.hash
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
�á�����d��̡$����a9�X��4לP
|
qi21_vae_1024_fp32.aimodel/main.mlirb
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:b4c3a184f7ee16f3f764ade7cca124a9a9b0ad613915ea8a0b58ffdf34d79c50
|
| 3 |
+
size 1012370701
|
qi21_vae_1024_fp32.aimodel/metadata.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"description" : "Qwen-Image-2.1 VAE decoder, 1024x1024, fp32: latents_packed [1,4096,64] (sampler output, normalised) -> image [1,4,1024,1024] RGBA in [-1,1]; unpack and latents*std+mean inside the graph. Source: Qwen\/Qwen-Image-2.1@790c926.",
|
| 3 |
+
"assetVersion" : "2.0",
|
| 4 |
+
"license" : "qwen-research",
|
| 5 |
+
"creationDate" : "20260925T071221Z",
|
| 6 |
+
"producer" : "coreai-core 1.0.0b2",
|
| 7 |
+
"creatorDefinedMetadata" : {
|
| 8 |
+
"strip" : {
|
| 9 |
+
"what" : "the .aimodel re-saved after coreai-torch's strip_debug_info: every op's source location (file, line, call stack) replaced by an unknown location; the ops and the weights are not touched",
|
| 10 |
+
"from_main_mlirb" : {
|
| 11 |
+
"bytes" : 1012440351,
|
| 12 |
+
"sha256" : "d82fc436a51e36dea17272c64e8dd667df7dcd0c1d485bf225319303ed823944"
|
| 13 |
+
},
|
| 14 |
+
"main_mlirb" : {
|
| 15 |
+
"bytes" : 1012370701,
|
| 16 |
+
"sha256" : "b4c3a184f7ee16f3f764ade7cca124a9a9b0ad613915ea8a0b58ffdf34d79c50"
|
| 17 |
+
},
|
| 18 |
+
"tool" : "conversion\/qwenimage21\/strip_bundle.py",
|
| 19 |
+
"versions" : {
|
| 20 |
+
"coreai-torch" : "0.4.1",
|
| 21 |
+
"coreai-core" : "1.0.0b2"
|
| 22 |
+
}
|
| 23 |
+
}
|
| 24 |
+
}
|
| 25 |
+
}
|
qi21_vae_256_fp32.aimodel/main.hash
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
|
qi21_vae_256_fp32.aimodel/main.mlirb
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:0dfd5cd6b8402850f5fa6d7a91b624e8c76188ceaecaab40d49681bed465633f
|
| 3 |
+
size 1012364804
|
qi21_vae_256_fp32.aimodel/metadata.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"creationDate" : "20260925T071101Z",
|
| 3 |
+
"producer" : "coreai-core 1.0.0b2",
|
| 4 |
+
"assetVersion" : "2.0",
|
| 5 |
+
"license" : "qwen-research",
|
| 6 |
+
"description" : "Qwen-Image-2.1 VAE decoder, 256x256, fp32: latents_packed [1,256,64] (sampler output, normalised) -> image [1,4,256,256] RGBA in [-1,1]; unpack and latents*std+mean inside the graph. Source: Qwen\/Qwen-Image-2.1@790c926.",
|
| 7 |
+
"creatorDefinedMetadata" : {
|
| 8 |
+
"strip" : {
|
| 9 |
+
"what" : "the .aimodel re-saved after coreai-torch's strip_debug_info: every op's source location (file, line, call stack) replaced by an unknown location; the ops and the weights are not touched",
|
| 10 |
+
"from_main_mlirb" : {
|
| 11 |
+
"bytes" : 1012434454,
|
| 12 |
+
"sha256" : "82396266f39abd444e11fd6b17b20347eeb7c3b8d5262b5522f877b13f527762"
|
| 13 |
+
},
|
| 14 |
+
"main_mlirb" : {
|
| 15 |
+
"bytes" : 1012364804,
|
| 16 |
+
"sha256" : "0dfd5cd6b8402850f5fa6d7a91b624e8c76188ceaecaab40d49681bed465633f"
|
| 17 |
+
},
|
| 18 |
+
"tool" : "conversion\/qwenimage21\/strip_bundle.py",
|
| 19 |
+
"versions" : {
|
| 20 |
+
"coreai-torch" : "0.4.1",
|
| 21 |
+
"coreai-core" : "1.0.0b2"
|
| 22 |
+
}
|
| 23 |
+
}
|
| 24 |
+
}
|
| 25 |
+
}
|
qi21_vae_512_fp32.aimodel/main.hash
ADDED
|
Binary file (32 Bytes). View file
|
|
|
qi21_vae_512_fp32.aimodel/main.mlirb
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d578ba43cf8a5f62134e3cd46885006f385153d8c1b1f83f9f7ce0a35215626f
|
| 3 |
+
size 1012366781
|
qi21_vae_512_fp32.aimodel/metadata.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"description" : "Qwen-Image-2.1 VAE decoder, 512x512, fp32: latents_packed [1,1024,64] (sampler output, normalised) -> image [1,4,512,512] RGBA in [-1,1]; unpack and latents*std+mean inside the graph. Source: Qwen\/Qwen-Image-2.1@790c926.",
|
| 3 |
+
"assetVersion" : "2.0",
|
| 4 |
+
"license" : "qwen-research",
|
| 5 |
+
"creationDate" : "20260925T071145Z",
|
| 6 |
+
"producer" : "coreai-core 1.0.0b2",
|
| 7 |
+
"creatorDefinedMetadata" : {
|
| 8 |
+
"strip" : {
|
| 9 |
+
"what" : "the .aimodel re-saved after coreai-torch's strip_debug_info: every op's source location (file, line, call stack) replaced by an unknown location; the ops and the weights are not touched",
|
| 10 |
+
"from_main_mlirb" : {
|
| 11 |
+
"bytes" : 1012436431,
|
| 12 |
+
"sha256" : "cf8b1b14704963bc912866b81482a2ac24b1367796c6f60eeed17e95e9282e56"
|
| 13 |
+
},
|
| 14 |
+
"main_mlirb" : {
|
| 15 |
+
"bytes" : 1012366781,
|
| 16 |
+
"sha256" : "d578ba43cf8a5f62134e3cd46885006f385153d8c1b1f83f9f7ce0a35215626f"
|
| 17 |
+
},
|
| 18 |
+
"tool" : "conversion\/qwenimage21\/strip_bundle.py",
|
| 19 |
+
"versions" : {
|
| 20 |
+
"coreai-torch" : "0.4.1",
|
| 21 |
+
"coreai-core" : "1.0.0b2"
|
| 22 |
+
}
|
| 23 |
+
}
|
| 24 |
+
}
|
| 25 |
+
}
|
qi21t_dit_full_bf16_dyn_iofp32.aimodel/main.hash
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
�i�7H'�Q�� ��ˋ)�����l�mG����
|
qi21t_dit_full_bf16_dyn_iofp32.aimodel/main.mlirb
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:9c69d137481c271ffd51fa99098187cb8b298d82fb88c56c15e66d47afc1caf8
|
| 3 |
+
size 14230567115
|
qi21t_dit_full_bf16_dyn_iofp32.aimodel/metadata.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"license" : "qwen-research",
|
| 3 |
+
"producer" : "coreai-core 1.0.0b2",
|
| 4 |
+
"creationDate" : "20261011T062903Z",
|
| 5 |
+
"description" : "Qwen-Image-2.1 DiT (full), bf16 weights+compute, fp32 I\/O, dynamic text\/image axes. Source: Qwen\/Qwen-Image-2.1-Turbo@d65dbc9.",
|
| 6 |
+
"assetVersion" : "2.0",
|
| 7 |
+
"creatorDefinedMetadata" : {
|
| 8 |
+
"strip" : {
|
| 9 |
+
"what" : "the .aimodel re-saved after coreai-torch's strip_debug_info: every op's source location (file, line, call stack) replaced by an unknown location; the ops and the weights are not touched",
|
| 10 |
+
"from_main_mlirb" : {
|
| 11 |
+
"bytes" : 14231004528,
|
| 12 |
+
"sha256" : "94804e70b71730201413aa962dda9092b8a2b158adeef191fa6322f4336aa9f9"
|
| 13 |
+
},
|
| 14 |
+
"main_mlirb" : {
|
| 15 |
+
"bytes" : 14230567115,
|
| 16 |
+
"sha256" : "9c69d137481c271ffd51fa99098187cb8b298d82fb88c56c15e66d47afc1caf8"
|
| 17 |
+
},
|
| 18 |
+
"tool" : "conversion\/qwenimage21\/strip_bundle.py",
|
| 19 |
+
"versions" : {
|
| 20 |
+
"coreai-torch" : "0.4.1",
|
| 21 |
+
"coreai-core" : "1.0.0b2"
|
| 22 |
+
}
|
| 23 |
+
}
|
| 24 |
+
}
|
| 25 |
+
}
|
qi21t_dit_full_int8lin_dyn_iofp32.aimodel/main.hash
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Q.p>�<X��ڧ
|
| 2 |
+
f��H&2�p��:ܺ-�
|
qi21t_dit_full_int8lin_dyn_iofp32.aimodel/main.mlirb
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:511d2e703e04b33c1358a9fddaa70a66e5cd482632c070b5c33add8cdcba2dc7
|
| 3 |
+
size 7560188326
|
qi21t_dit_full_int8lin_dyn_iofp32.aimodel/metadata.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"assetVersion" : "2.0",
|
| 3 |
+
"producer" : "coreai-core 1.0.0b2",
|
| 4 |
+
"creationDate" : "20261011T065052Z",
|
| 5 |
+
"license" : "qwen-research",
|
| 6 |
+
"description" : "Qwen-Image-2.1 DiT (full), int8 per-block-32 Linear weights (symmetric), bf16 compute, fp32 I\/O, dynamic text\/image axes. Source: Qwen\/Qwen-Image-2.1-Turbo@d65dbc9.",
|
| 7 |
+
"creatorDefinedMetadata" : {
|
| 8 |
+
"strip" : {
|
| 9 |
+
"what" : "the .aimodel re-saved after coreai-torch's strip_debug_info: every op's source location (file, line, call stack) replaced by an unknown location; the ops and the weights are not touched",
|
| 10 |
+
"from_main_mlirb" : {
|
| 11 |
+
"bytes" : 7560697655,
|
| 12 |
+
"sha256" : "3190edb18e6167499ae015b1660532846a1f4aa1d6de5cdbcf1dae5e6d2c752e"
|
| 13 |
+
},
|
| 14 |
+
"main_mlirb" : {
|
| 15 |
+
"bytes" : 7560188326,
|
| 16 |
+
"sha256" : "511d2e703e04b33c1358a9fddaa70a66e5cd482632c070b5c33add8cdcba2dc7"
|
| 17 |
+
},
|
| 18 |
+
"tool" : "conversion\/qwenimage21\/strip_bundle.py",
|
| 19 |
+
"versions" : {
|
| 20 |
+
"coreai-torch" : "0.4.1",
|
| 21 |
+
"coreai-core" : "1.0.0b2"
|
| 22 |
+
}
|
| 23 |
+
}
|
| 24 |
+
}
|
| 25 |
+
}
|
tokenizer/chat_template.jinja
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{%- if tools %}
|
| 2 |
+
{{- '<|im_start|>system\n' }}
|
| 3 |
+
{%- if messages[0].role == 'system' %}
|
| 4 |
+
{%- if messages[0].content is string %}
|
| 5 |
+
{{- messages[0].content }}
|
| 6 |
+
{%- else %}
|
| 7 |
+
{%- for content in messages[0].content %}
|
| 8 |
+
{%- if 'text' in content %}
|
| 9 |
+
{{- content.text }}
|
| 10 |
+
{%- endif %}
|
| 11 |
+
{%- endfor %}
|
| 12 |
+
{%- endif %}
|
| 13 |
+
{{- '\n\n' }}
|
| 14 |
+
{%- endif %}
|
| 15 |
+
{{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within <tools></tools> XML tags:\n<tools>" }}
|
| 16 |
+
{%- for tool in tools %}
|
| 17 |
+
{{- "\n" }}
|
| 18 |
+
{{- tool | tojson }}
|
| 19 |
+
{%- endfor %}
|
| 20 |
+
{{- "\n</tools>\n\nFor each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\n<tool_call>\n{\"name\": <function-name>, \"arguments\": <args-json-object>}\n</tool_call><|im_end|>\n" }}
|
| 21 |
+
{%- else %}
|
| 22 |
+
{%- if messages[0].role == 'system' %}
|
| 23 |
+
{{- '<|im_start|>system\n' }}
|
| 24 |
+
{%- if messages[0].content is string %}
|
| 25 |
+
{{- messages[0].content }}
|
| 26 |
+
{%- else %}
|
| 27 |
+
{%- for content in messages[0].content %}
|
| 28 |
+
{%- if 'text' in content %}
|
| 29 |
+
{{- content.text }}
|
| 30 |
+
{%- endif %}
|
| 31 |
+
{%- endfor %}
|
| 32 |
+
{%- endif %}
|
| 33 |
+
{{- '<|im_end|>\n' }}
|
| 34 |
+
{%- endif %}
|
| 35 |
+
{%- endif %}
|
| 36 |
+
{%- set image_count = namespace(value=0) %}
|
| 37 |
+
{%- set video_count = namespace(value=0) %}
|
| 38 |
+
{%- for message in messages %}
|
| 39 |
+
{%- if message.role == "user" %}
|
| 40 |
+
{{- '<|im_start|>' + message.role + '\n' }}
|
| 41 |
+
{%- if message.content is string %}
|
| 42 |
+
{{- message.content }}
|
| 43 |
+
{%- else %}
|
| 44 |
+
{%- for content in message.content %}
|
| 45 |
+
{%- if content.type == 'image' or 'image' in content or 'image_url' in content %}
|
| 46 |
+
{%- set image_count.value = image_count.value + 1 %}
|
| 47 |
+
{%- if add_vision_id %}Picture {{ image_count.value }}: {% endif -%}
|
| 48 |
+
<|vision_start|><|image_pad|><|vision_end|>
|
| 49 |
+
{%- elif content.type == 'video' or 'video' in content %}
|
| 50 |
+
{%- set video_count.value = video_count.value + 1 %}
|
| 51 |
+
{%- if add_vision_id %}Video {{ video_count.value }}: {% endif -%}
|
| 52 |
+
<|vision_start|><|video_pad|><|vision_end|>
|
| 53 |
+
{%- elif 'text' in content %}
|
| 54 |
+
{{- content.text }}
|
| 55 |
+
{%- endif %}
|
| 56 |
+
{%- endfor %}
|
| 57 |
+
{%- endif %}
|
| 58 |
+
{{- '<|im_end|>\n' }}
|
| 59 |
+
{%- elif message.role == "assistant" %}
|
| 60 |
+
{{- '<|im_start|>' + message.role + '\n' }}
|
| 61 |
+
{%- if message.content is string %}
|
| 62 |
+
{{- message.content }}
|
| 63 |
+
{%- else %}
|
| 64 |
+
{%- for content_item in message.content %}
|
| 65 |
+
{%- if 'text' in content_item %}
|
| 66 |
+
{{- content_item.text }}
|
| 67 |
+
{%- endif %}
|
| 68 |
+
{%- endfor %}
|
| 69 |
+
{%- endif %}
|
| 70 |
+
{%- if message.tool_calls %}
|
| 71 |
+
{%- for tool_call in message.tool_calls %}
|
| 72 |
+
{%- if (loop.first and message.content) or (not loop.first) %}
|
| 73 |
+
{{- '\n' }}
|
| 74 |
+
{%- endif %}
|
| 75 |
+
{%- if tool_call.function %}
|
| 76 |
+
{%- set tool_call = tool_call.function %}
|
| 77 |
+
{%- endif %}
|
| 78 |
+
{{- '<tool_call>\n{"name": "' }}
|
| 79 |
+
{{- tool_call.name }}
|
| 80 |
+
{{- '", "arguments": ' }}
|
| 81 |
+
{%- if tool_call.arguments is string %}
|
| 82 |
+
{{- tool_call.arguments }}
|
| 83 |
+
{%- else %}
|
| 84 |
+
{{- tool_call.arguments | tojson }}
|
| 85 |
+
{%- endif %}
|
| 86 |
+
{{- '}\n</tool_call>' }}
|
| 87 |
+
{%- endfor %}
|
| 88 |
+
{%- endif %}
|
| 89 |
+
{{- '<|im_end|>\n' }}
|
| 90 |
+
{%- elif message.role == "tool" %}
|
| 91 |
+
{%- if loop.first or (messages[loop.index0 - 1].role != "tool") %}
|
| 92 |
+
{{- '<|im_start|>user' }}
|
| 93 |
+
{%- endif %}
|
| 94 |
+
{{- '\n<tool_response>\n' }}
|
| 95 |
+
{%- if message.content is string %}
|
| 96 |
+
{{- message.content }}
|
| 97 |
+
{%- else %}
|
| 98 |
+
{%- for content in message.content %}
|
| 99 |
+
{%- if content.type == 'image' or 'image' in content or 'image_url' in content %}
|
| 100 |
+
{%- set image_count.value = image_count.value + 1 %}
|
| 101 |
+
{%- if add_vision_id %}Picture {{ image_count.value }}: {% endif -%}
|
| 102 |
+
<|vision_start|><|image_pad|><|vision_end|>
|
| 103 |
+
{%- elif content.type == 'video' or 'video' in content %}
|
| 104 |
+
{%- set video_count.value = video_count.value + 1 %}
|
| 105 |
+
{%- if add_vision_id %}Video {{ video_count.value }}: {% endif -%}
|
| 106 |
+
<|vision_start|><|video_pad|><|vision_end|>
|
| 107 |
+
{%- elif 'text' in content %}
|
| 108 |
+
{{- content.text }}
|
| 109 |
+
{%- endif %}
|
| 110 |
+
{%- endfor %}
|
| 111 |
+
{%- endif %}
|
| 112 |
+
{{- '\n</tool_response>' }}
|
| 113 |
+
{%- if loop.last or (messages[loop.index0 + 1].role != "tool") %}
|
| 114 |
+
{{- '<|im_end|>\n' }}
|
| 115 |
+
{%- endif %}
|
| 116 |
+
{%- endif %}
|
| 117 |
+
{%- endfor %}
|
| 118 |
+
{%- if add_generation_prompt %}
|
| 119 |
+
{{- '<|im_start|>assistant\n' }}
|
| 120 |
+
{%- endif %}
|
tokenizer/processor_config.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"image_processor": {
|
| 3 |
+
"data_format": "channels_first",
|
| 4 |
+
"do_convert_rgb": true,
|
| 5 |
+
"do_normalize": true,
|
| 6 |
+
"do_rescale": true,
|
| 7 |
+
"do_resize": true,
|
| 8 |
+
"image_mean": [
|
| 9 |
+
0.5,
|
| 10 |
+
0.5,
|
| 11 |
+
0.5
|
| 12 |
+
],
|
| 13 |
+
"image_processor_type": "Qwen2VLImageProcessorFast",
|
| 14 |
+
"image_std": [
|
| 15 |
+
0.5,
|
| 16 |
+
0.5,
|
| 17 |
+
0.5
|
| 18 |
+
],
|
| 19 |
+
"merge_size": 2,
|
| 20 |
+
"patch_size": 16,
|
| 21 |
+
"resample": 3,
|
| 22 |
+
"rescale_factor": 0.00392156862745098,
|
| 23 |
+
"size": {
|
| 24 |
+
"longest_edge": 16777216,
|
| 25 |
+
"shortest_edge": 65536
|
| 26 |
+
},
|
| 27 |
+
"temporal_patch_size": 2
|
| 28 |
+
},
|
| 29 |
+
"processor_class": "Qwen3VLProcessor",
|
| 30 |
+
"video_processor": {
|
| 31 |
+
"data_format": "channels_first",
|
| 32 |
+
"default_to_square": true,
|
| 33 |
+
"do_convert_rgb": true,
|
| 34 |
+
"do_normalize": true,
|
| 35 |
+
"do_rescale": true,
|
| 36 |
+
"do_resize": true,
|
| 37 |
+
"do_sample_frames": true,
|
| 38 |
+
"fps": 2,
|
| 39 |
+
"image_mean": [
|
| 40 |
+
0.5,
|
| 41 |
+
0.5,
|
| 42 |
+
0.5
|
| 43 |
+
],
|
| 44 |
+
"image_std": [
|
| 45 |
+
0.5,
|
| 46 |
+
0.5,
|
| 47 |
+
0.5
|
| 48 |
+
],
|
| 49 |
+
"max_frames": 768,
|
| 50 |
+
"merge_size": 2,
|
| 51 |
+
"min_frames": 4,
|
| 52 |
+
"patch_size": 16,
|
| 53 |
+
"resample": 3,
|
| 54 |
+
"rescale_factor": 0.00392156862745098,
|
| 55 |
+
"return_metadata": false,
|
| 56 |
+
"size": {
|
| 57 |
+
"longest_edge": 25165824,
|
| 58 |
+
"shortest_edge": 4096
|
| 59 |
+
},
|
| 60 |
+
"temporal_patch_size": 2,
|
| 61 |
+
"video_processor_type": "Qwen3VLVideoProcessor"
|
| 62 |
+
}
|
| 63 |
+
}
|
tokenizer/tokenizer.json
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:be75606093db2094d7cd20f3c2f385c212750648bd6ea4fb2bf507a6a4c55506
|
| 3 |
+
size 11422650
|
tokenizer/tokenizer_config.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"add_prefix_space": false,
|
| 3 |
+
"backend": "tokenizers",
|
| 4 |
+
"bos_token": null,
|
| 5 |
+
"clean_up_tokenization_spaces": false,
|
| 6 |
+
"eos_token": "<|im_end|>",
|
| 7 |
+
"errors": "replace",
|
| 8 |
+
"extra_special_tokens": [
|
| 9 |
+
"<|im_start|>",
|
| 10 |
+
"<|im_end|>",
|
| 11 |
+
"<|object_ref_start|>",
|
| 12 |
+
"<|object_ref_end|>",
|
| 13 |
+
"<|box_start|>",
|
| 14 |
+
"<|box_end|>",
|
| 15 |
+
"<|quad_start|>",
|
| 16 |
+
"<|quad_end|>",
|
| 17 |
+
"<|vision_start|>",
|
| 18 |
+
"<|vision_end|>",
|
| 19 |
+
"<|vision_pad|>",
|
| 20 |
+
"<|image_pad|>",
|
| 21 |
+
"<|video_pad|>"
|
| 22 |
+
],
|
| 23 |
+
"is_local": true,
|
| 24 |
+
"model_max_length": 262144,
|
| 25 |
+
"pad_token": "<|endoftext|>",
|
| 26 |
+
"processor_class": "Qwen3VLProcessor",
|
| 27 |
+
"split_special_tokens": false,
|
| 28 |
+
"tokenizer_class": "Qwen2Tokenizer",
|
| 29 |
+
"unk_token": null
|
| 30 |
+
}
|