Text-to-Image
Diffusers
Safetensors
English
Chinese
QwenImage21Pipeline
sdnq
int4
uint4
image-generation
image-editing
apple-silicon
8-bit precision
Instructions to use ixim/Image21-INT4 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Diffusers
How to use ixim/Image21-INT4 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-INT4", 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
File size: 4,681 Bytes
9116984 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | """Validate pipeline structure and bind an evaluation to exact files."""
import hashlib
import json
from pathlib import Path
from scripts.integrity import sha256
REVISION = 'b3179ad355be050328e483a9dfdd9e60cd62adfa'
def _quantization(config):
raw = config.get('quantization_config') or {}
method = str(raw.get('quant_method', '')).lower()
dtype = str(raw.get('weights_dtype', '')).lower()
return method == 'sdnq' and dtype == 'uint4' and not raw.get('use_quantized_matmul')
def validate_model_structure(root):
root = Path(root)
required = ['model_index.json', 'processor/tokenizer.json',
'processor/tokenizer_config.json', 'processor/preprocessor_config.json',
'scheduler/scheduler_config.json']
required += [f'{component}/config.json' for component in ('transformer', 'text_encoder', 'vae')]
missing = [path for path in required if not (root / path).is_file()]
if missing:
raise ValueError(f'Missing model components/configs: {missing}')
model_index = json.loads((root / 'model_index.json').read_text(encoding='utf-8'))
if model_index.get('_class_name') != 'QwenImage21Pipeline':
raise ValueError('Unexpected pipeline class')
flags = []
for component in ('transformer', 'text_encoder', 'vae'):
folder = root / component
config = json.loads((folder / 'config.json').read_text(encoding='utf-8'))
files = sorted(folder.glob('*.safetensors'))
indexes = list(folder.glob('*.safetensors.index.json'))
if not files or len(indexes) > 1 or (len(files) > 1 and not indexes):
raise ValueError(f'Missing or ambiguous shards: {component}')
index = json.loads(indexes[0].read_text(encoding='utf-8'))['weight_map'] if indexes else None
if index is not None and set(index.values()) != {file.name for file in files}:
raise ValueError(f'Incomplete shard index: {component}')
names = set()
for file in files:
from safetensors import safe_open
with safe_open(str(file), framework='np') as handle:
keys = set(handle.keys())
if not keys or names & keys:
raise ValueError(f'Empty or duplicate tensors: {file}')
if index is not None and any(index.get(key) != file.name for key in keys):
raise ValueError(f'Shard tensor mapping mismatch: {file}')
names |= keys
if index is not None and names != set(index):
raise ValueError(f'Missing indexed tensors: {component}')
quantized = _quantization(config)
if component == 'vae' and quantized:
raise ValueError('VAE must remain floating point')
if component != 'vae':
flags.append(quantized)
if flags not in ([False, False], [True, True]):
raise ValueError('Transformer and text encoder must use the same precision')
return 'int4' if all(flags) else 'bf16'
def inference_files(root):
root = Path(root)
result = [root / 'model_index.json']
for component in ('transformer', 'text_encoder', 'vae', 'processor', 'scheduler'):
result.extend(path for path in (root / component).rglob('*')
if path.is_file() and not any(part.startswith('.') for part in path.relative_to(root).parts))
return sorted(result)
def model_identity(root, verified_rows=None):
root = Path(root)
kind = validate_model_structure(root)
known = {row['path']: row for row in verified_rows} if verified_rows is not None else None
rows = []
for file in inference_files(root):
name = file.relative_to(root).as_posix()
if known is not None:
if name not in known or file.stat().st_size != known[name]['size']:
raise ValueError(f'Preverified inventory mismatch: {name}')
row = known[name]
else:
row = {'path': name, 'size': file.stat().st_size, 'sha256': sha256(file)}
rows.append(row)
encoded = json.dumps(rows, sort_keys=True, separators=(',', ':')).encode()
return {'kind': kind, 'base_revision': REVISION, 'files': rows,
'fingerprint': hashlib.sha256(encoded).hexdigest()}
def validate_roles(baseline, quantized):
if baseline['kind'] != 'bf16' or quantized['kind'] != 'int4':
raise ValueError('Comparison requires a BF16 baseline and an INT4 candidate')
if baseline['fingerprint'] == quantized['fingerprint']:
raise ValueError('Baseline and candidate are identical')
if baseline['base_revision'] != quantized['base_revision']:
raise ValueError('Different upstream revisions')
|