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
File size: 8,714 Bytes
e9190ff | 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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | """Validate versioned editing evidence and render a local inspection gallery."""
import argparse
import html
import json
from pathlib import Path
from PIL import Image
from scripts.editing_protocol import (PROTOCOL, DEFAULT_SEEDS, validate_seeds, image_diagnostics,
load_input, edit_dimensions)
from scripts.integrity import sha256
from scripts.provenance import validate_roles
from scripts.report import load_records, compare_pixels
def validate_run(root, inputs):
root, inputs = Path(root), Path(inputs)
env = json.loads((root/'environment.json').read_text())
cases = json.loads((root/'cases.json').read_text(encoding='utf-8'))
complete = json.loads((root/'COMPLETE.json').read_text())
if env['protocol'] != PROTOCOL or env['before_load_memory']['allocated_bytes'] != 0:
raise ValueError('Wrong protocol or non-fresh process')
if sha256(root/'cases.json') != env['cases_sha256']:
raise ValueError('Case definitions changed')
validate_seeds(cases, env['seeds'])
records = load_records(root)
expected = {(c['id'], s) for c in cases for s in env['seeds']}
if len({c['id'] for c in cases}) != len(cases) or records.keys() != expected:
raise ValueError('Incomplete or mismatched case/seed matrix')
if (complete['records'] != len(records)
or complete['records_sha256'] != sha256(root/'records.jsonl')):
raise ValueError('Completion record differs from evidence')
for case in cases:
if Path(case['input_file']).name != case['input_file']:
raise ValueError('Invalid input path')
path = inputs/case['input_file']
if sha256(path) != case['input_sha256']:
raise ValueError('Input hash mismatch')
size = edit_dimensions(load_input(path).size, env['resolution'])
for seed in env['seeds']:
row = records[case['id'], seed]
for key, value in dict(protocol=PROTOCOL, prompt=case['prompt'],
source_seed=case.get('source_seed'), input_file=case['input_file'],
input_sha256=case['input_sha256'], width=size[0], height=size[1],
output_resolution=env['resolution'], steps=env['steps'], cfg=1.,
kv_cache=env['kv_cache'], vae_tiling=env['vae_tiling'],
offload=env['offload']).items():
if row[key] != value:
raise ValueError('Record setting mismatch: '+key)
if Path(row['image']).name != row['image']:
raise ValueError('Invalid output path')
with Image.open(root/row['image']) as image:
if image.size != size:
raise ValueError('PNG dimensions differ from requested dimensions')
for key, value in image_diagnostics(image).items():
if row[key] != value:
raise ValueError('Image diagnostic mismatch: '+key)
if 'decode_latents' in row:
if (Path(row['decode_latents']).name != row['decode_latents']
or sha256(root/row['decode_latents']) != row['decode_latents_sha256']):
raise ValueError('Decoder evidence changed')
return env, records, cases
def validate_suite(root, source_root=None):
root = Path(root)
runs = {p: validate_run(root/p, root/'inputs') for p in ('bf16', 'int8')}
a, b = (runs[p][0] for p in ('bf16', 'int8'))
validate_roles(a['model_identity'], b['model_identity'])
for key in ('protocol', 'seeds', 'resolution', 'steps', 'kv_cache', 'vae_tiling',
'offload', 'warmup', 'generator_device', 'cases_sha256', 'gpu', 'cuda',
'packages', 'source_sha256', 'upstream_source_sha256', 'scheduler_config',
'vae_dtype', 'vae_tiles'):
if a[key] != b[key]:
raise ValueError('Paired runtime mismatch: '+key)
if runs['bf16'][1].keys() != runs['int8'][1].keys():
raise ValueError('Paired cases/seeds differ')
if source_root:
required_sources = {'benchmark_edits_v2.py', 'editing_protocol.py', 'benchmark.py', 'runtime.py'}
if set(a['source_sha256']) != required_sources:
raise ValueError('Incomplete measured source inventory')
canonical = json.loads((Path(source_root).parent/'benchmarks/editing-v2.json').read_text(encoding='utf-8'))
if len(canonical) != 5 or runs['bf16'][2] != canonical:
raise ValueError('Release requires all five declared editing cases')
for key, value in dict(seeds=list(DEFAULT_SEEDS), resolution=1024, steps=40,
warmup=True, kv_cache=True, vae_tiling=False,
offload='model', generator_device='cpu', offload_aux_fix=True).items():
if any(run[0].get(key) != value for run in runs.values()):
raise ValueError('Unexpected editing release setting: '+key)
for name, digest in a['source_sha256'].items():
if sha256(Path(source_root)/name) != digest:
raise ValueError('Measured source differs from shipped source: '+name)
isolation = [json.loads(line) for line in (root/'process-isolation.jsonl').read_text().splitlines()]
if len(isolation) != 2 or {r['precision'] for r in isolation} != {'bf16', 'int8'}:
raise ValueError('Missing independent process evidence')
for index, row in enumerate(isolation):
if (row['exit_code'] != 0
or row.get('inference_pid', row['pid']) != runs[row['precision']][0]['pid']):
raise ValueError('Process did not complete successfully')
if row['ended'] < row['started'] or (index and row['started'] < isolation[index-1]['ended']):
raise ValueError('Evaluation processes overlapped')
for key, row in runs['bf16'][1].items():
if row['sigmas'] != runs['int8'][1][key]['sigmas']:
raise ValueError('Sampling schedule mismatch')
return runs
def render(root):
root = Path(root)
runs = validate_suite(root)
rows = []
parts = ['<!doctype html><meta charset="utf-8"><title>Editing v2 inspection</title>',
'<style>body{font:16px sans-serif;margin:24px}img{max-width:32%;height:auto} '
'details img{max-width:48%}article{border-top:1px solid #aaa;margin-top:32px}</style>',
'<h1>Editing v2: independent editing seeds</h1><p>Input / BF16 / INT8. '
'Open PNGs for 100% inspection. White, black and checker composites are display aids; '
'raw RGBA outputs are unchanged. Pixel similarity and alpha fractions are not quality scores.</p>']
for case in runs['bf16'][2]:
for seed in runs['bf16'][0]['seeds']:
key = case['id'], seed
a, b = (runs[p][1][key] for p in ('bf16', 'int8'))
metrics = compare_pixels(root/'bf16'/a['image'], root/'int8'/b['image'])
rows.append(dict(case_id=case['id'], seed=seed, **metrics))
parts.append(f'<article><h2>{html.escape(case["id"])} / {seed}</h2>'
f'<p>{html.escape(case["prompt"])}</p>')
for src in ['inputs/'+case['input_file'], 'bf16/'+a['image'], 'int8/'+b['image']]:
parts.append(f'<a href="{html.escape(src)}"><img src="{html.escape(src)}"></a>')
for display in ('alpha', 'white', 'black', 'checker'):
parts.append(f'<details><summary>{display}</summary>')
for p, row in [('bf16', a), ('int8', b)]:
src = f'{p}/diagnostics/{Path(row["image"]).stem}-{display}.png'
if not (root/src).is_file():
raise ValueError('Missing diagnostic preview: '+src)
parts.append(f'<a href="{src}"><img loading="lazy" src="{src}"></a>')
parts.append('</details>')
parts.append('</article>')
(root/'comparison.html').write_text('\n'.join(parts), encoding='utf-8')
summary = dict(protocol=PROTOCOL, pairs=len(rows), cases=len(runs['bf16'][2]),
seeds=runs['bf16'][0]['seeds'], resolution=runs['bf16'][0]['resolution'],
observations='See AUDIT.md; similarity is not an edit-success score.', comparisons=rows)
(root/'summary.json').write_text(json.dumps(summary, indent=2), encoding='utf-8')
return summary
if __name__ == '__main__':
ap = argparse.ArgumentParser(__doc__)
ap.add_argument('--root', required=True)
args = ap.parse_args()
print(json.dumps(render(args.root), indent=2))
|