Text-to-Image
Diffusers
Safetensors
English
Chinese
QwenImage21Pipeline
bitsandbytes
int8
image-generation
image-editing
rgba
8-bit precision
Instructions to use ixim/Image21-INT8 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Diffusers
How to use ixim/Image21-INT8 with Diffusers:
pip install -U diffusers transformers accelerate
import torch from diffusers import DiffusionPipeline # switch to "mps" for apple devices pipe = DiffusionPipeline.from_pretrained("ixim/Image21-INT8", dtype=torch.bfloat16, device_map="cuda") prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" image = pipe(prompt).images[0] - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- Draw Things
- DiffusionBee
| """Device-only offload workaround for the pinned bitsandbytes 0.50.2 stack. | |
| Parent Module.to() recursively invokes _apply(), not each child's to(). | |
| Linear8bitLt.to() moves auxiliary tensors, but this path is bypassed by a | |
| parent move. Keep CB aliases and SCB/outlier state colocated with the weight. | |
| This is instance-local; checkpoint tensors and installed packages are unchanged. | |
| """ | |
| from types import MethodType | |
| import torch | |
| def patch_int8_device_moves(model): | |
| from bitsandbytes.nn import Linear8bitLt | |
| for layer in model.modules(): | |
| if not isinstance(layer, Linear8bitLt) or getattr(layer, '_int8_move_patched', False): | |
| continue | |
| if layer.state.has_fp16_weights: | |
| raise ValueError('Offload helper only supports inference INT8 weights') | |
| original = layer._apply | |
| def apply(self, fn, recurse=True, _original=original): | |
| result = _original(fn, recurse=recurse) | |
| device = self.weight.device | |
| # Parameter auxiliaries are used before init_8bit_state(); state | |
| # auxiliaries are used afterwards. Never duplicate the CB storage. | |
| if self.weight.CB is not None: | |
| self.weight.CB = self.weight.data | |
| if self.weight.SCB is not None: | |
| self.weight.SCB = self.weight.SCB.to(device) | |
| for name, value in vars(self.state).items(): | |
| if isinstance(value, torch.Tensor): | |
| setattr(self.state, name, self.weight.data if name == 'CB' else value.to(device)) | |
| return result | |
| layer._apply = MethodType(apply, layer) | |
| layer._int8_move_patched = True | |
| def enable_int8_cpu_offload(pipe): | |
| """Install auxiliary-tensor movement before standard model CPU offload.""" | |
| for name in ('text_encoder', 'transformer'): | |
| patch_int8_device_moves(getattr(pipe, name)) | |
| pipe.enable_model_cpu_offload() | |
| def load_int8_pipeline(model, local_files_only=False): | |
| """Load/offload components sequentially to avoid a combined CUDA load peak.""" | |
| from diffusers import QwenImage21Pipeline, QwenImage21Transformer2DModel | |
| from transformers import Qwen3VLForConditionalGeneration | |
| components = {} | |
| for name, cls in [('transformer', QwenImage21Transformer2DModel), | |
| ('text_encoder', Qwen3VLForConditionalGeneration)]: | |
| component = cls.from_pretrained(model, subfolder=name, dtype=torch.bfloat16, | |
| local_files_only=local_files_only) | |
| if not getattr(component, 'is_loaded_in_8bit', False): | |
| raise ValueError('Expected saved bitsandbytes INT8 component: '+name) | |
| patch_int8_device_moves(component) | |
| component.to('cpu') | |
| torch.cuda.empty_cache() | |
| components[name] = component | |
| pipe = QwenImage21Pipeline.from_pretrained(model, dtype=torch.bfloat16, | |
| local_files_only=local_files_only, **components) | |
| enable_int8_cpu_offload(pipe) | |
| return pipe | |