ladparis commited on
Commit
50860a6
·
verified ·
1 Parent(s): 9e9c881

Upload folder using huggingface_hub

Browse files
Files changed (4) hide show
  1. README.md +22 -7
  2. __pycache__/app.cpython-314.pyc +0 -0
  3. app.py +222 -0
  4. requirements.txt +10 -0
README.md CHANGED
@@ -1,13 +1,28 @@
1
  ---
2
- title: Cosmos3 Super Text2Image
3
- emoji: 😻
4
- colorFrom: pink
5
- colorTo: pink
6
  sdk: gradio
7
- sdk_version: 6.24.0
8
- python_version: '3.12'
9
  app_file: app.py
 
 
 
10
  pinned: false
 
11
  ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: Cosmos3-Super-Text2Image
3
+ emoji: 🌌
4
+ colorFrom: indigo
5
+ colorTo: purple
6
  sdk: gradio
7
+ sdk_version: 6.15.1
 
8
  app_file: app.py
9
+ python_version: "3.12"
10
+ short_description: NVIDIA Cosmos3-Super 64B text-to-image, NVFP4 quantization
11
+ startup_duration_timeout: 1h
12
  pinned: false
13
+ license: other
14
  ---
15
 
16
+ # 🌌 Cosmos3-Super-Text2Image
17
+
18
+ Demo of [nvidia/Cosmos3-Super-Text2Image](https://huggingface.co/nvidia/Cosmos3-Super-Text2Image) — a **64B**-parameter omnimodal world model for Physical AI — generating high-fidelity images from text on a single NVIDIA Blackwell GPU (ZeroGPU) via **NVFP4** weight-only quantization (torchao / NVIDIA ModelOpt).
19
+
20
+ ## Notes
21
+
22
+ - NVIDIA officially tests this checkpoint **only at BF16**. NVFP4 is unofficial and may show quality drift compared to the full-precision recipe.
23
+ - The 64B transformer does not fit in BF16 on a single GPU, so it is loaded weight-only quantized to NVFP4 and streamed onto the ZeroGPU `xlarge` (96 GB) allocation.
24
+ - The app doubles as an **MCP server** (`mcp_server=True`) — the `generate` tool is exposed with its docstring and type hints.
25
+
26
+ ## License
27
+
28
+ Model released under [OpenMDW 1.1](https://openmdw.ai/license/1-1/).
__pycache__/app.cpython-314.pyc ADDED
Binary file (11.1 kB). View file
 
app.py ADDED
@@ -0,0 +1,222 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ os.environ.setdefault("PYTORCH_CUDA_ALLOC_CONF", "expandable_segments:True")
3
+
4
+ import spaces # noqa: F401 must precede torch / diffusers
5
+ import tempfile
6
+ from pathlib import Path
7
+
8
+ import gradio as gr
9
+ import torch
10
+ from torch.utils._python_dispatch import is_traceable_wrapper_subclass, transform_subclass
11
+
12
+ # --- ZeroGPU packer support for NVFP4 tensor-subclass weights -----------------
13
+ # ZeroGPU's empty_fake calls empty_like + set_ on each parameter to build the
14
+ # pinned-CPU mirror it streams from. Those ops don't make sense on tensor-subclass
15
+ # wrappers (NVFP4Tensor, etc.) which contain multiple inner storages. Patch
16
+ # empty_fake to recurse into wrapper subclasses via transform_subclass so each
17
+ # inner tensor gets packed individually.
18
+ import spaces.zero.torch.patching as _zg_patching
19
+
20
+ _orig_empty_fake = _zg_patching.empty_fake
21
+
22
+
23
+ def _empty_fake_subclass_aware(tensor):
24
+ if is_traceable_wrapper_subclass(tensor):
25
+ def _per_inner(_name, inner):
26
+ inner_fake = _orig_empty_fake(inner)
27
+ # Register inner-tensor aliases so the packer actually packs each storage.
28
+ _zg_patching.cuda_aliases[inner_fake] = inner
29
+ return inner_fake
30
+ return transform_subclass(tensor, _per_inner)
31
+ return _orig_empty_fake(tensor)
32
+
33
+
34
+ _zg_patching.empty_fake = _empty_fake_subclass_aware
35
+
36
+ from diffusers import AutoModel, Cosmos3OmniPipeline, TorchAoConfig
37
+ from diffusers.schedulers.scheduling_unipc_multistep import UniPCMultistepScheduler
38
+ from torchao.prototype.mx_formats import NVFP4WeightOnlyConfig
39
+ from torchao.prototype.mx_formats.nvfp4_tensor import NVFP4Tensor
40
+
41
+ # --- NVFP4 dtype-safety shim --------------------------------------------------
42
+ # Cosmos3's time_proj emits fp32 sinusoidals; vanilla F.linear upcasts the weight,
43
+ # but the NVFP4 dispatch handlers expect input.dtype == weight.orig_dtype. Wrap the
44
+ # matmul-family handlers to cast non-NVFP4 tensor inputs to the weight's orig_dtype
45
+ # on the fly.
46
+ def _make_dtype_safe(orig_handler):
47
+ def wrapped(func, types, args, kwargs):
48
+ weight = next((a for a in args if isinstance(a, NVFP4Tensor)), None)
49
+ if weight is not None:
50
+ target = weight.orig_dtype
51
+ new_args = tuple(
52
+ a.to(target) if isinstance(a, torch.Tensor)
53
+ and not isinstance(a, NVFP4Tensor)
54
+ and a.dtype != target
55
+ and a.is_floating_point()
56
+ else a
57
+ for a in args
58
+ )
59
+ return orig_handler(func, types, new_args, kwargs)
60
+ return orig_handler(func, types, args, kwargs)
61
+ return wrapped
62
+
63
+
64
+ _aten = torch.ops.aten
65
+ _nvfp4_table = NVFP4Tensor._ATEN_OP_TABLE[NVFP4Tensor]
66
+ for _f in [
67
+ torch.nn.functional.linear,
68
+ _aten.linear.default,
69
+ _aten.addmm.default,
70
+ _aten.mm.default,
71
+ _aten.matmul.default,
72
+ ]:
73
+ if _f in _nvfp4_table:
74
+ _nvfp4_table[_f] = _make_dtype_safe(_nvfp4_table[_f])
75
+
76
+ # --- Model loading ------------------------------------------------------------
77
+ MODEL_ID = "nvidia/Cosmos3-Super-Text2Image"
78
+
79
+ quant_config = TorchAoConfig(NVFP4WeightOnlyConfig())
80
+
81
+ transformer = AutoModel.from_pretrained(
82
+ MODEL_ID,
83
+ subfolder="transformer",
84
+ quantization_config=quant_config,
85
+ torch_dtype=torch.bfloat16,
86
+ )
87
+
88
+ pipe = Cosmos3OmniPipeline.from_pretrained(
89
+ MODEL_ID,
90
+ transformer=transformer,
91
+ torch_dtype=torch.bfloat16,
92
+ enable_safety_checker=False,
93
+ )
94
+ pipe.scheduler = UniPCMultistepScheduler.from_config(pipe.scheduler.config, flow_shift=3.0)
95
+ pipe.to("cuda")
96
+
97
+ RESOLUTIONS = {
98
+ "1024\u00d71024 (1:1)": (1024, 1024),
99
+ "1280\u00d7720 (16:9)": (1280, 720),
100
+ "720\u00d71280 (9:16)": (720, 1280),
101
+ "1024\u00d7768 (4:3)": (1024, 768),
102
+ "768\u00d71024 (3:4)": (768, 1024),
103
+ }
104
+
105
+
106
+ def _duration(prompt, resolution, steps, *_):
107
+ w, h = RESOLUTIONS[resolution]
108
+ # Measured: ~14s per step at 1024\u00d71024 NVFP4 dequant; scale by pixel count + margin.
109
+ per_step = 18 * (w * h) / (1024 * 1024)
110
+ return min(1500, int(60 + per_step * int(steps)))
111
+
112
+
113
+ @spaces.GPU(duration=_duration, size="xlarge")
114
+ def generate(
115
+ prompt: str,
116
+ resolution: str = "1024\u00d71024 (1:1)",
117
+ steps: int = 35,
118
+ guidance: float = 4.0,
119
+ negative_prompt: str = "",
120
+ seed: int = 0,
121
+ randomize_seed: bool = True,
122
+ progress=gr.Progress(track_tqdm=True),
123
+ ):
124
+ """Generate a high-fidelity image from a text prompt with NVIDIA Cosmos3-Super-Text2Image (64B, NVFP4).
125
+
126
+ Args:
127
+ prompt: Text description of the image to generate.
128
+ resolution: Output resolution / aspect ratio label.
129
+ steps: Number of denoising steps (higher = more detail, slower).
130
+ guidance: Classifier-free guidance scale.
131
+ negative_prompt: What to avoid in the image (optional).
132
+ seed: Random seed for reproducibility.
133
+ randomize_seed: If true, pick a fresh random seed each run.
134
+
135
+ Returns:
136
+ The generated PNG image path and the seed that was used.
137
+ """
138
+ if not prompt or not prompt.strip():
139
+ raise gr.Error("Please enter a prompt.")
140
+ width, height = RESOLUTIONS[resolution]
141
+ if randomize_seed:
142
+ seed = int(torch.randint(0, 2**31 - 1, (1,)).item())
143
+ generator = torch.Generator(device="cuda").manual_seed(int(seed))
144
+
145
+ result = pipe(
146
+ prompt=prompt,
147
+ negative_prompt=negative_prompt or None,
148
+ num_frames=1,
149
+ height=height,
150
+ width=width,
151
+ num_inference_steps=int(steps),
152
+ guidance_scale=float(guidance),
153
+ generator=generator,
154
+ output_type="pil",
155
+ )
156
+ img = result.video[0]
157
+ out_dir = Path(tempfile.mkdtemp(prefix="cosmos3_"))
158
+ p = out_dir / "image.png"
159
+ img.save(p)
160
+ return str(p), seed
161
+
162
+
163
+ CSS = """
164
+ .gradio-container { max-width: 1100px !important; margin: auto !important; }
165
+ """
166
+
167
+ EXAMPLES = [
168
+ ["A photorealistic image of an autonomous delivery robot navigating a rainy city street at night, neon reflections on wet asphalt, cinematic lighting"],
169
+ ["A robotic arm on a factory assembly line precisely placing a component, industrial setting, sharp focus, high detail"],
170
+ ["A cozy reading nook with a robot sitting under a cherry blossom tree, holding an open book, soft afternoon light"],
171
+ ["An aerial view of a smart warehouse with automated guided vehicles moving between shelving, clean modern architecture"],
172
+ ]
173
+
174
+ with gr.Blocks(theme=gr.themes.Soft(), css=CSS, title="Cosmos3-Super \u00b7 Text2Image") as demo:
175
+ gr.Markdown(
176
+ "# \U0001f30c Cosmos3-Super-Text2Image\n"
177
+ "Demo of [nvidia/Cosmos3-Super-Text2Image](https://huggingface.co/nvidia/Cosmos3-Super-Text2Image) "
178
+ "\u2014 a **64B**-parameter omnimodal world model for Physical AI \u2014 generating high-fidelity "
179
+ "images from text on a single Blackwell GPU via **NVFP4** weight-only quantization.\n\n"
180
+ "> NVIDIA officially tests this checkpoint only at BF16; NVFP4 is unofficial and may show "
181
+ "quality drift vs. the full-precision recipe."
182
+ )
183
+ with gr.Row():
184
+ prompt = gr.Textbox(
185
+ show_label=False,
186
+ placeholder="A photo of a robot reading a book under a cherry tree\u2026",
187
+ container=False,
188
+ scale=4,
189
+ )
190
+ run = gr.Button("Generate", variant="primary", scale=1)
191
+
192
+ out = gr.Image(label="Output", type="filepath", format="png", height=640)
193
+
194
+ with gr.Accordion("Advanced settings", open=False):
195
+ negative_prompt = gr.Textbox(label="Negative prompt", value="")
196
+ resolution = gr.Dropdown(
197
+ label="Resolution",
198
+ choices=list(RESOLUTIONS),
199
+ value="1024\u00d71024 (1:1)",
200
+ )
201
+ steps = gr.Slider(label="Inference steps", minimum=10, maximum=50, value=35, step=1)
202
+ guidance = gr.Slider(label="Guidance scale", minimum=1.0, maximum=8.0, value=4.0, step=0.1)
203
+ with gr.Row():
204
+ randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
205
+ seed = gr.Number(label="Seed", value=0, precision=0)
206
+
207
+ inputs = [prompt, resolution, steps, guidance, negative_prompt, seed, randomize_seed]
208
+ outputs = [out, seed]
209
+
210
+ gr.Examples(
211
+ examples=EXAMPLES,
212
+ inputs=[prompt],
213
+ outputs=outputs,
214
+ fn=generate,
215
+ cache_examples=True,
216
+ cache_mode="lazy",
217
+ )
218
+
219
+ run.click(generate, inputs, outputs)
220
+ prompt.submit(generate, inputs, outputs)
221
+
222
+ demo.queue().launch(mcp_server=True)
requirements.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ diffusers @ git+https://github.com/huggingface/diffusers.git
2
+ transformers
3
+ accelerate
4
+ torchvision
5
+ torchaudio
6
+ av
7
+ imageio
8
+ imageio-ffmpeg
9
+ sentencepiece
10
+ torchao