ajh-code commited on
Commit
96fe467
·
verified ·
1 Parent(s): 672175d

Add edit.py

Browse files
Files changed (1) hide show
  1. edit.py +177 -0
edit.py ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Run one Mage-Flow Edit XPO3 image edit."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ import json
8
+ import os
9
+ from pathlib import Path
10
+ import sys
11
+ import time
12
+
13
+ from PIL import Image
14
+
15
+
16
+ ROOT = Path(__file__).resolve().parent
17
+ for path in (ROOT / "runtime", ROOT / "vendor"):
18
+ sys.path.insert(0, str(path))
19
+
20
+
21
+ def parse_args() -> argparse.Namespace:
22
+ parser = argparse.ArgumentParser(description=__doc__)
23
+ parser.add_argument("reference", type=Path)
24
+ parser.add_argument("instruction")
25
+ parser.add_argument("--output", type=Path, default=Path("edited.png"))
26
+ parser.add_argument("--seed", type=int, default=1)
27
+ parser.add_argument("--max-size", type=int, default=1024)
28
+ parser.add_argument("--disable-fused-gelu-up", action="store_true")
29
+ parser.add_argument("--disable-fp4-bridge", action="store_true")
30
+ parser.add_argument("--disable-accelerated-attention", action="store_true")
31
+ parser.add_argument("--disable-direct-hnd", action="store_true")
32
+ parser.add_argument("--report", type=Path)
33
+ return parser.parse_args()
34
+
35
+
36
+ def main() -> int:
37
+ args = parse_args()
38
+ os.environ.setdefault("CUBLAS_WORKSPACE_CONFIG", ":4096:8")
39
+
40
+ import torch
41
+ from portable_turbo_runtime import (
42
+ close_pipeline_optimization_runtimes,
43
+ generation_optimization_context,
44
+ load_pipeline_from_files,
45
+ transformer_config,
46
+ )
47
+
48
+ if not torch.cuda.is_available():
49
+ raise RuntimeError("XPO3 requires an NVIDIA CUDA GPU")
50
+ torch.cuda.set_device(0)
51
+ properties = torch.cuda.get_device_properties(0)
52
+ if (properties.major, properties.minor) != (12, 0):
53
+ raise RuntimeError(
54
+ "this XPO3 build requires an NVIDIA Blackwell SM120 GPU; "
55
+ f"found compute capability {properties.major}.{properties.minor}"
56
+ )
57
+
58
+ diffusion_model = (
59
+ ROOT / "Mage-Flow-Edit-XPO3-NVFP4.safetensors"
60
+ )
61
+ text_encoder = ROOT / "qwen3vl_4b_fp8_scaled.safetensors"
62
+ vae = ROOT / "Mage-Flow-VAE.safetensors"
63
+ config = transformer_config(diffusion_model)
64
+ profile = config["quantization_config"]["xpo3_runtime_profile"]
65
+ bridge_blocks = ",".join(
66
+ sorted(
67
+ profile["fp4_bridge_scales"],
68
+ key=lambda value: int(value),
69
+ )
70
+ )
71
+ attention_steps = ",".join(
72
+ str(value) for value in profile["attention_steps"]
73
+ )
74
+ attention_blocks = ",".join(
75
+ str(value) for value in profile["attention_blocks"]
76
+ )
77
+
78
+ torch.manual_seed(args.seed)
79
+ torch.cuda.manual_seed_all(args.seed)
80
+ torch.cuda.reset_peak_memory_stats(0)
81
+ started = time.perf_counter()
82
+ pipe, load_report = load_pipeline_from_files(
83
+ diffusion_model=diffusion_model,
84
+ text_encoder=text_encoder,
85
+ vae=vae,
86
+ support_root=ROOT / "resources" / "edit",
87
+ fused_gelu_library=ROOT / "runtime/libmage_nvfp4_gelu_up.so",
88
+ bridge_up_library=ROOT / "runtime/libmage_nvfp4_bridge_up.so",
89
+ bridge_down_library=(
90
+ ROOT / "runtime/libmage_nvfp4_prequantized_down.so"
91
+ ),
92
+ torch=torch,
93
+ )
94
+ for module in (
95
+ pipe.model.txt_enc,
96
+ pipe.model.transformer,
97
+ pipe.model.vae,
98
+ ):
99
+ module.to("cuda:0")
100
+ torch.cuda.synchronize()
101
+ load_seconds = time.perf_counter() - started
102
+
103
+ reference = Image.open(args.reference).convert("RGB")
104
+ generation_started = time.perf_counter()
105
+ with torch.inference_mode():
106
+ with generation_optimization_context(
107
+ pipe=pipe,
108
+ torch=torch,
109
+ enable_fused_gelu_up=not args.disable_fused_gelu_up,
110
+ enable_fp4_bridge=not args.disable_fp4_bridge,
111
+ bridge_blocks=bridge_blocks,
112
+ enable_attention_accel=(
113
+ not args.disable_accelerated_attention
114
+ ),
115
+ enable_direct_hnd=not args.disable_direct_hnd,
116
+ attention_steps=attention_steps,
117
+ attention_blocks=attention_blocks,
118
+ steps=int(profile["steps"]),
119
+ static_shift=float(profile["static_shift"]),
120
+ cfg=float(profile["cfg"]),
121
+ required_cfg=float(profile["cfg"]),
122
+ expected_steps=int(profile["steps"]),
123
+ ) as feature_manifest:
124
+ images = pipe.edit(
125
+ [args.instruction],
126
+ [[reference]],
127
+ neg_prompts=[" "],
128
+ seeds=[args.seed],
129
+ steps=int(profile["steps"]),
130
+ cfg=float(profile["cfg"]),
131
+ max_size=args.max_size,
132
+ static_shift=float(profile["static_shift"]),
133
+ prompt_template="mage-flow-edit",
134
+ vl_cond_long_edge=384,
135
+ batch_cfg=False,
136
+ )
137
+ torch.cuda.synchronize()
138
+ generation_seconds = time.perf_counter() - generation_started
139
+ if not feature_manifest["restoration"]["all_restored"]:
140
+ raise RuntimeError("XPO3 feature state did not restore after editing")
141
+
142
+ args.output.parent.mkdir(parents=True, exist_ok=True)
143
+ images[0].save(args.output)
144
+ report = {
145
+ "schema_version": "mage-flow-edit-xpo3-cli-v1",
146
+ "reference": str(args.reference.resolve()),
147
+ "instruction": args.instruction,
148
+ "output": str(args.output.resolve()),
149
+ "seed": args.seed,
150
+ "max_size": args.max_size,
151
+ "gpu": {
152
+ "name": properties.name,
153
+ "compute_capability": (
154
+ f"{properties.major}.{properties.minor}"
155
+ ),
156
+ },
157
+ "load_and_placement_seconds": load_seconds,
158
+ "generation_seconds": generation_seconds,
159
+ "peak_allocated_bytes": int(torch.cuda.max_memory_allocated(0)),
160
+ "load": load_report,
161
+ "active_feature_manifest": feature_manifest,
162
+ }
163
+ if args.report is not None:
164
+ args.report.parent.mkdir(parents=True, exist_ok=True)
165
+ args.report.write_text(
166
+ json.dumps(report, indent=2, sort_keys=True) + "\n",
167
+ encoding="utf-8",
168
+ )
169
+ print(json.dumps(report, indent=2, sort_keys=True))
170
+ cleanup = close_pipeline_optimization_runtimes(pipe)
171
+ if not cleanup["all_closed_without_error"]:
172
+ raise RuntimeError(f"XPO3 native cleanup failed: {cleanup}")
173
+ return 0
174
+
175
+
176
+ if __name__ == "__main__":
177
+ raise SystemExit(main())