Spaces:
Runtime error
Runtime error
Commit History
-
Name mask classes from the request, not the canonical label table
The legend showed "label 2" where hepatic tumor should be. The cause is worse than a missing name: the saved CT mask does not use canonical 132-class IDs at all. Upstream's filter_mask_with_organs (scripts/sample_mask.py:154) rewrites each requested organ to its 1-based position in the request: for i in range(len(anatomy_list)): combine_label[combine_label == anatomy_list[i]] = -(i + 1) So [liver, hepatic tumor, spleen, gallbladder] yields mask values 1..4 in that order. Naming those through label_dict.json happened to be right for liver and spleen and wrong for everything else -- "hepatic tumor" landed on dummy1 and rendered as a placeholder, while gallbladder was confidently displayed as "pancreas". Silent mislabelling is the real defect here; the placeholder is just the visible symptom. Every preset was affected: Full chest 5/5 wrong (all five lung lobes shown as liver/spleen/pancreas/kidney), Whole abdomen 9/10, Pelvis organs 3/3, Liver + lesion 2/4. GenerationResul…ca3f97e
-
Stream volumes by URL, cache checkpoints, reclaim archive space, quiet logs
Stream the viewer payload instead of inlining it. render_viewer() now hands niivue a /gradio_api/file= link resolved against document.baseURI, rather than base64-encoding the volume and mask into the page. A 46 MB CT was becoming ~61 MB of HTML built and shipped synchronously; measured on a test volume the payload drops 58x. app.launch() gains allowed_paths for the output dir. NV_GENERATE_VIEWER_MODE=base64 restores the old path if a deployment blocks file serving. Cache checkpoints across runs. scripts/inference.py issues five torch.load() calls per CT generation -- ~3.35 GB re-read and re-deserialised every time. _cached_torch_load() memoises them by (path, size, mtime) with LRU eviction under a byte budget (NV_GENERATE_CKPT_CACHE_GIB, default 8). This is host RAM, not VRAM: CT's weights are ~3.35 GB against a 96 GB xlarge slice, so VRAM was never the limit -- the 48-80 GB figure is activations, not parameters. Reclaim the mask archive. Once extracted, the 11.6 GB .zip is never rea…f265752 -
Move CPU work off the GPU, and log phase timings
The logs showed a CT run writing its NIfTI output ~10-15s before the image appeared. That gap was the mask label scan (nibabel + np.unique over the whole volume) and the viewer's base64 encode of both the image and mask — neither of which touches CUDA, but both of which ran inside the @spaces.GPU function and so were billed against the ZeroGPU allocation. Split for all three models. The decorated function now does inference only and hands the result to a gr.State; a following .then() does the label scan and the viewer encode on CPU. CT additionally gains generate(scan_labels=False) so the label pass can be deferred, and resolve_anatomy_labels() to run it afterwards. Added utils/timing.py: a nesting phase() context manager and a Stopwatch, all output prefixed [nv-generate] so it greps cleanly out of Gradio/MONAI/tqdm noise. Instrumented startup (clone, per-model prefetch, mask extraction, UI build) and generation (inference, label scan, viewer encode with payload size). A run now read…261940d -
Fix weight links resolving to nothing
775850b linked weights from the HF cache but produced dangling symlinks, so every model file was unreadable: "[Errno 2] No such file or directory: 'models/autoencoder_v1.pt'". os.link() on a symlink source hard-links the symlink itself, target string included, rather than the file it points at. hf_hub_download returns the snapshot entry, which is a *relative* symlink into the cache (../../../blobs/<sha>). Linking that into <upstream>/models/ carried the relative target along, where it resolved to <upstream>/../../blobs/<sha> -- nothing. The result passed through upstream's `saved to:` unverified. The second-order failure: a dangling symlink is False to exists() but True to lexists(), so link() and symlink() both fail EEXIST and shutil.copy2 then writes *through* the broken link, which is where the Errno 2 surfaced. Three fixes: resolve the source with realpath() before linking so the blob is linked; unlink any stale dst first, dangling ones included; and verify the result resolves, …d5d94ae -
Prefetch weights at startup and stop duplicating them on disk
Three problems, all on the CT path, all visible in the Space logs: 1. The whole weight fetch ran inside the @spaces.GPU function. CT pulls ~15 GB (11.6 GB of it the anatomy-mask archive) and then unzips it, which alone is ~130s against a 90s GPU budget. prefetch_weights() now runs at import time in app.py, outside the decorator, so the GPU allocation only pays for inference. It also pre-extracts the mask archive, which find_masks.py then skips. 2. run_paired_ct() called ensure_weights() even though upstream scripts/inference.py calls download_model_data() itself — with a different root_dir. That wrote the 11.6 GB archive to two separate locations. Removed; ensure_weights now defaults to the same DATA_DIR upstream uses. 3. Upstream copies each file out of the HF cache with shutil.copy2, storing everything twice. _LinkingShutil hard-links instead: one inode, two names, zero extra bytes. Moving the blob would corrupt hf_hub_download's blobs/snapshots layou…775850b
-
Initial commit: NV-Generate Gradio showcase
A Hugging Face Spaces app that surfaces NVIDIA Medtech's three open-weight 3D medical image generators (CT, MR, MR Brain) under one console-style UI, all running the latest MAISI-v2 rectified-flow variants. Architecture ============ - app.py — Gradio Blocks entrypoint. Hero card landing → per-model workspace switched via gr.Group visibility. Auto-clones the NV-Generate-CTMR upstream repo on first run so the same flow works locally and on HF Spaces. - pipelines/ base.py — GenerationRequest / GenerationResult dataclasses. _runner.py — Shared driver: chdir into upstream, write modified configs into configs/_temp/, invoke scripts.diff_model_infer or scripts.inference, harvest the resulting NIfTI(s). ct.py — Paired image + 132-class mask (rflow-ct). mr.py — Multi-contrast MR image-only (rflow-mr). mr_brain.py — Brain MR multi-sequence (rflow-mr-brain). - viewer/ niivue_embed.py — Render…ab1db83