Spaces:
Runtime error
Runtime error
Commit History
-
fix(ui): trigger resize after normalise so wavesurfer redraws
Unverified signaturenormalised_audio starts as visible=False (display:none), so wavesurfer initialises at 0px width and stays stuck in "processing". Dispatching a resize event after the handler responds tells wavesurfer to re-measure the container and draw the waveform correctly.d794fd0 -
fix(lyrics): fallback to transformers/MPS when MLX fails
Unverified signatureMLX load failure and the worker-thread stream crash both now fall back to Qwen 2.5 7B via transformers on MPS. Fallback at load time catches missing/incompatible MLX weights; fallback at generate time catches the RuntimeError: There is no Stream(gpu, 0) bug. The global singleton is swapped on first failure so subsequent calls skip MLX.dc09969 -
fix(lora): accept XL SFT PEFT-style LoRA keys in validator
Unverified signatureXL SFT uses LLM-style naming (layers.X.cross_attn.k_proj) not diffusion-style (transformer.blocks.X.attn.to_k). LoRAs trained with PEFT wrap keys as base_model.model.layers.*. Add both prefix and module-suffix sets so community XL SFT LoRAs pass validation.158626f -
fix(pipeline): switch default 5Hz LM from 0.6B to 1.7B
Unverified signature0.6B enters a degenerate loop generating bpm: 66!!... tokens, wasting ~66 s per generation and returning incomplete metadata. 1.7B is already bundled in the ACE-Step/Ace-Step1.5 umbrella so no preload changes needed for Spaces.f9a1a8e
-
docs: refresh guides with deploy-session learnings
Unverified signatureCLAUDE.md - Fact #1: ACE-Step is vendored as git submodule (not pip-install) — upstream pyproject declares nano-vllm which isn't on PyPI. - Fact #5: lyrics LM token-level prompt slice (string-level fails on skip_special_tokens=True). - Fact #6: checkpoint resolver wants vendor/ace-step/checkpoints/, NOT ./models/<org>/<repo>/; no cache-mirror dance (cp -al fails with EXDEV on ZeroGPU). - Fact #8: Advanced controls accordion documented. - ACE-Step gotchas: filled in 10 items (nano-vllm, initialize_service async, gradio pin conflict, inference_steps default, infer_method sde/ode, CoT toggles, demucs 4.0 vs 4.1 API, MLX worker-thread stream, HFLM prompt-strip, hf_transfer dep). - HF Spaces deployment: 13 items (Python 3.13 default, sdk_version, preload sizes, README YAML validation, EXDEV mirror, HF_MODULES_CACHE, Cloudflare 80s SSE, force-push bootstrap, Apple git fetch failure, osxkeychain HTTPS storage, GPG override per-tag, hf CLI vs…01f5c21
-
fix(ui): make checkbox checked state visible
Unverified signatureNative browser checkboxes were invisible against the Brutalist Mono dark palette — the checkmark indicator washed out on dark surfaces and the box outline was nearly imperceptible. Replaced with a custom appearance:none style: - Unchecked: dark fill, 1.5 px muted-ink border - Checked: white fill with a black checkmark SVG drawn inline via data URI (no external asset, CSP-safe) - Hover: border brightens to full ink - Focus: 2 px white outline Affects all checkboxes inside .ams-content (Advanced accordion's 4 LM CoT toggles + ADG, plus any future ones).7401bf7 -
feat(ui): add advanced controls accordion — inference steps, cfg, infer method, seed, lm cot, schedule, metadata
Unverified signatureUser feedback: outputs feel samey regardless of prompt. Root cause: GenerationParams.inference_steps defaults to 8 (ACE-Step turbo), too few for the XL SFT model to actually express variation. Also guidance_scale, infer_method, shift, ADG, and CoT flags all left at dataclass defaults. New ``Advanced ▼`` accordion under every song mode (Generate / Cover / Extend / Edit; lyrics mode is its own Qwen path and doesn't need it). Four groups: - Diffusion: inference_steps (8-80, default 27), guidance_scale (1-15, default 7.0), infer_method (ode|sde), seed (number, -1=random). - CFG schedule + shift + ADG. - 5Hz LM (CoT): thinking + use_cot_caption + use_cot_metas + use_cot_language now defaulted ON; LM temperature / top_p / top_k / cfg / negative_prompt sliders. - Music metadata: bpm / keyscale / timesignature / vocal_language manual overrides. ace_pipeline.generate passes all of these through to GenerationParams. Output metadata JSON now echoes the advanced + lm…c287b6a -
fix(ui): restore desktop sidebar — don't apply min-width:0 to .ams-sidebar
Unverified signaturePrevious commit broadcasted min-width: 0 to .ams-body > * to fix the mobile waveform overflow. That selector also matched .ams-sidebar, overriding its hard min-width: 188px and collapsing the sidebar to a vertical sliver on desktop — visible as single characters stacked top-to-bottom where the nav + history should be. Scoping the flex-shrink fix to .ams-content only (which already has min-width: 0 set directly). Sidebar keeps its 188 px minimum.7dd8eb5 -
fix(ui): stop wavesurfer controls + timestamps disappearing during re-render
Unverified signatureSwitched from clipping the inner wavesurfer wrappers (which hid the 1:00 timestamp + play/skip/forward controls during transient re-renders) to clipping only at the outer .ams-out-audio panel and the canvas itself. Inner .component-wrapper / .controls / .timestamps now render freely. Plus min-height reserved on .timestamps (24px) and .controls (60px) so neither collapses to zero while wavesurfer is recalculating its grid layout. Without this reservation, the user sees the play controls vanish + reappear when the URL bar shows/hides on mobile or any other viewport-height tick triggers a wavesurfer reflow.990fcda -
fix(ui): stop layout 'dance' on mobile — cage audio waveform width
Unverified signatureThe Gradio audio component uses wavesurfer.js, which renders the waveform at a pixel-per-second rate. For a 60s clip that's ~600px wide, which on mobile (~360px viewport) pushes the parent column past the viewport edge. Worse: flex children default to min-width: auto, meaning they CANNOT shrink below their intrinsic content size — so the column itself widens to fit the waveform, and the whole layout 'dances' between the pre-generation narrow state and the post-generation wide state. Fix: - min-width: 0 on .ams-content + .ams-body > * so flex children can shrink below content intrinsic width - overflow: hidden + max-width: 100% on .ams-out-audio so the waveform is clipped at the column edge - width/max-width: 100% on every wavesurfer container layer (.component-wrapper, .waveform-container, #waveform, canvas) - max-width: 100% + overflow-x: hidden on .ams-content as a last-line defense against any other wide childde7d60a -
fix(deploy): redirect HF_MODULES_CACHE to /tmp — ~/.cache is read-only at runtime
Unverified signatured625691 -
fix(deploy): symlink hf preloads into fork's checkpoint dir + strip prompt tokens in lyrics
Unverified signature1. The fork's AceStepHandler resolves checkpoints relative to its own install dir (vendor/ace-step/checkpoints/), not ./models/<org>/<repo>/. Previous symlink path was unused → fork triggered async auto-download during initialize_service(), returned before it finished, then the generate_music() call hit 'Model not fully initialized'. Now we symlink the preloaded Ace-Step1.5 snapshot's contents flat into vendor/ace-step/checkpoints/ and the acestep-v15-xl-sft snapshot as the matching subdir, so the resolver sees real files at module init. 2. _HFLM.generate stripped the prompt via string startswith match, but tokenizer.decode(skip_special_tokens=True) removes the <|im_start|> markers from the decoded output — so the prefix never matched and the system + user turns leaked into the lyrics output. Now slice at the token level: out[0][prompt_len:] decoded separately.03ddd85 -
fix(deploy): skip cp -al mirror on zerogpu — exdev hardlink failure across filesystems
Unverified signature1de4459 -
chore(debug): write startup prints to stderr (hf logs stream stderr more reliably)
Unverified signaturea37fc46 -
chore(debug): add startup phase prints to diagnose hf spaces hang
Unverified signature851d183 -
feat(deploy): vendor ace-step as submodule, skip nano-vllm via sys.path injection
Unverified signatureace-step's pyproject pins 'nano-vllm; sys_platform != darwin' which isn't on PyPI (their README says manually 'cd acestep/third_parts/nano-vllm && pip install .'). All nano-vllm imports in ace-step are lazy (function- scoped, try/except wrapped), so the package works without it. Vendored at vendor/ace-step (git submodule of the apple-silicon fork which has a looser gradio pin >=6.5.1). requirements.txt now lists ace-step's transitive deps directly. app.py adds vendor/ace-step to sys.path BEFORE importing ace_pipeline so 'from acestep import ...' resolves to the vendored copy. Upstream updates: 'git submodule update --remote vendor/ace-step'.f118cd9 -
fix(deploy): switch to apple-silicon ace-step fork — no nano-vllm, looser gradio pin
Unverified signaturec8c3fc2 -
fix(deploy): align gradio to ace-step's pin (6.2.0) — drop our own pin, let hf inject
Unverified signature0495c62 -
fix(deploy): pin python_version 3.11 — hf spaces base bumped to 3.13 which breaks ace-step pin
Unverified signature014974f -
fix(deploy): trim README short_description to fit HF Spaces 60-char cap
Unverified signature0bc7217 -
fix(lyrics): re-create mlx_lm generation_stream in worker thread
Unverified signatureThe previous fix wrapped generate() in mx.stream(mx.gpu) but only installed the *default* gpu stream for the current thread. mlx_lm also uses a module-level generation_stream = mx.new_stream(...) created at import time on the main thread; wired_limit().__exit__ then calls mx.synchronize(generation_stream) which crashes from the Gradio worker thread with 'There is no Stream(gpu, 0) in current thread.' Re-assign mlx_lm.generate.generation_stream to a fresh stream created in the current thread before every generate() call. Safe because Gradio runs at default_concurrency_limit=1.0d2d5a8 -
test(post): rewrite separate_stems test for demucs.apply.apply_model path
Unverified signaturefc8c46f -
fix(deploy): align demucs warmup to runtime model name (htdemucs not htdemucs_ft)
Unverified signaturedb12e72 -
feat(deploy): preload all hub models + warm demucs on spaces
Unverified signatureExpand HF Spaces ``preload_from_hub`` to cover everything the app actually touches on first interaction: ACE-Step base + XL-SFT, both LoRA presets, and Qwen 2.5 7B Instruct. Mirror the list in ``_PRELOAD_REPOS`` so the symlink loop knows about them. Add a demucs ``htdemucs_ft`` warmup at module load (gated by ``SPACE_ID``) because demucs weights live on dl.fbaipublicfiles.com — outside the HF preload reach. Preload disk budget: ~10 GB (ACE base) + ~16 GB (XL-SFT) + ~120 MB + ~120 MB (LoRAs) + ~15 GB (Qwen) + ~320 MB (demucs runtime) ≈ 42 GB. Within the ZeroGPU persistent-storage ceiling but worth keeping an eye on if upstream weights grow.3f9c655 -
fix(post): use lower-level demucs API + stringify stem paths for gr.Files
Unverified signaturedemucs 4.0.x has no demucs.api.Separator (added in 4.1). Refactor separate_stems() to use demucs.pretrained.get_model + demucs.apply.apply_model so the installed wheel works without a forced upgrade of the apple-silicon torch stack. Also stringify PosixPath values before handing to gr.Files — Gradio 6.14's pydantic FileData model rejects PosixPath inputs.b992e76 -
fix(lyrics): wrap mlx-lm generate in mx.stream(mx.gpu) for Gradio worker threads
Unverified signatureGradio dispatches handlers via anyio.to_thread.run_sync; the worker thread's per-thread MLX default stream is uninitialised, so mlx-lm's wired_limit() fails with RuntimeError 'There is no Stream(gpu, 0) in current thread.' Wrapping the generate() call in an mx.stream(mx.gpu) context installs a GPU stream for the duration of the call.a81cc03 -
fix(lora): force pipe load before unload_lora() when DiT is still cold
Unverified signatureCold pipe + apply_stack() called from backend.dispatch() before pipe.generate() runs _ensure_loaded() — pipe._dit is None and dit.unload_lora() crashes with AttributeError. Empty stack short-circuits when the DiT is missing; non-empty stack forces _ensure_loaded() so the LoRA has a DiT to attach to.901e296 -
fix(deps): add hf_transfer for fast hub downloads
Unverified signature43af060 -
fix(deploy): pin gradio to 6.14 to match running version + claude.md note refresh
Unverified signatureca276db -
fix(deploy): per-mode duration estimator handles cover/extend/edit/lyrics signatures
Unverified signature05f6b53 -
fix(deploy): align m7 with claude.md — models/<org>/<repo> layout + gpu estimator
Unverified signaturea5459fd
-
feat(deploy): m7 — hf spaces readme + cache bootstrap + zerogpu decorator
Unverified signaturea30ec7c -
feat(ui): m6 polish — in-memory history sidebar + _safe_call error wrapper
Unverified signatureH2 + H3 from the M6 plan, in one commit because the app.py hunks are interleaved. - _HISTORY list + _history_render + _history_push helpers, capped at 12 newest-first entries. Each on_*_click handler now returns a third output (history HTML) wired into the dynamic gr.HTML in the sidebar. - _safe_call wrapper centralises LoRAValidationError / ValueError / FileNotFoundError / RuntimeError -> gr.Error translation so each click handler stays a single call into modes.*. MPS RuntimeErrors get the PYTORCH_ENABLE_MPS_FALLBACK hint. - theme.CSS gains compact .ams-history-row styling (mono mode token + ellipsis sans label) and hides the history block at the 640 px mobile breakpoint.3a8ec98 -
feat(ui): expand tooltips.py + apply info= to cover/extend/edit/lyrics tabs
Unverified signatureAdds COVER_*, EXTEND_*, EDIT_*, LYRICS_*, LORA_*, and POST_* tooltip strings to the central tooltips module and wires them into the corresponding ui.py builders. gr.Audio / gr.File widgets don't accept info= in Gradio 6.14 — those are skipped (visible labels carry the intent already). gr.Button likewise has no info= so the post-process action row keeps its descriptive button labels as the affordance.0ef5d8d -
feat(post): wire separate stems / normalise / mp3 export buttons in output panel (m5 g2)
Unverified signature7388985 -
feat(post): add demucs stems, lufs normalisation, mp3 export
Unverified signatureb260242 -
feat(ui): wire lyrics tab + cross-tab use-in-generate handoff (m4)
Unverified signaturefdfc10d -
feat(lyrics): add qwen 2.5 7b lazy loader with mlx and transformers backends
Unverified signature9c07a74 -
feat(ui): wire cover/extend/edit tabs into the sidebar layout (m3 e3+e4)
Unverified signatureReplaces the three placeholder Markdowns in pane_cover / pane_extend / pane_edit with full form builders mirroring the Generate tab's structure (2-column row, LoRA accordion, output panel). Each tab carries mode-specific inputs: - Cover: reference audio + audio_cover_strength slider - Extend: seed audio + extra_duration + experimental repaint params - Edit: source audio + sub_mode pills (repaint/flow_edit) + segment_start_s/segment_end_s + experimental flow-morph params Shared chrome (LoRA accordion + Output/Metadata panels) factored into _build_lora_accordion / _build_output_panel helpers so future mode additions don't duplicate the same 30-line block. Fields not yet wired to GenerationParams (repaint_mode, repaint_strength, chunk_mask_mode, latent_crossfade_frames, wav_crossfade_s, flow_source_caption, flow_n_*, cover_noise_strength) are surfaced under "(experimental)" accordions with inline notes explaining they're captured but no-ops until ACE-Step adds the fields upstream. Th…adb7693 -
feat(pipeline): wire cover/extend/edit task_types in studio.generate
Unverified signature26dc3a4 -
feat(modes): add cover, extend, edit handlers with sub-mode dispatch
Unverified signaturea2eae29 -
fix(lora): point manifest at the actually-published ACE-Step LoRAs
Unverified signatureThe plan / D2 manifest used placeholder HF paths for RapMachine, Chinese Rap, Lyric2Vocal, Text2Samples — three of which were announced in the ACE-Step roadmap but never published as standalone HuggingFace repos. Clicking any preset chip surfaced a 404 toast from huggingface_hub. What actually exists today (verified via huggingface.co/ACE-Step): - ACE-Step/ACE-Step-v1-chinese-rap-LoRA filename: pytorch_lora_weights.safetensors (524 MB) - ACE-Step/ACE-Step-v1.5-chinese-new-year-LoRA filename: adapter_model.safetensors (88 MB) Note that the filenames differ between the two repos (Chinese Rap uses the diffusers/PEFT pytorch_lora_weights name, New Year uses the newer adapter_model name) — that's why manifest entries carry an explicit ``filename`` field per preset. Manifest pared to those two real LoRAs. ui.py's preset radio now reads choices dynamically from lora_stack.load_presets() so future manifest changes don't require code edits. Tests updated to verify schema + the ACE-Step/ …24b2854 -
feat(ui): wire single-lora picker into generate tab (m2 d5)
Unverified signatureAdds a collapsed-by-default LoRA accordion in the Generate tab between the vocal-mode row and the Generate button. Inside: - Preset radio (4 bundled + None) — rendered as pill-shaped chips - Custom .safetensors upload with a dashed drop zone - Strength slider (0.0-1.5, default 0.95) - Active LoRA display (Markdown showing name + scale + kind) - Hidden gr.State carrying the resolved {name, scale, path, sha256} dict Picking a preset triggers lora_stack.download_preset + sniff + sets state and clears the upload. Uploading a custom file triggers sniff + sets state and resets the preset to "None". The Generate button passes the state to backend.dispatch as params["loras"] = [state] (or [] when None). Reflects the apple-silicon fork's single-LoRA reality — a multi-row stack is deferred until upstream adds multi-adapter support. Brutalist Mono / IBM Plex chrome preserved via elem_classes hooks and matching CSS in theme.py. Specificity bumped on the preset-radio selector so it beats the gen…a1d8cb5 -
feat(backend): apply lora stack before mode dispatch
Unverified signature96012ce -
feat(lora): add single-lora stack apply + disable
Unverified signaturee701df3 -
feat(lora): add preset registry with hf-download helper
Unverified signature321117e -
feat(lora): add safetensors header sniff with ace-step module check
Unverified signaturec9f8dd1 -
fix(ui): kill .styler bands + label icons + deepen pill contrast
Unverified signatureUser feedback on the mobile screenshot flagged three remaining issues: 1. Slate-blue horizontal bands above and below the Generate button. Cause: Gradio wraps each Row/Form in a <div class="styler …"> whose default background is var(--border-color-primary) — which we set to #1F1F1F (BORDER). On Samsung's cool-temperature display that #1F1F1F reads as bluish-grey. Force .styler inside .ams-content to background:transparent so the form rows blend into the panel. 2. Tiny 11x11 music-note / braces SVG icons next to OUTPUT and METADATA labels. Gradio inlines these inside the <label> as a decoration. The wireframe does not show them; they overlap the label text at small sizes. Hide via .ams-content .ams-out label svg { display:none } while keeping the LARGE empty-state SVG (which lives in a separate .empty.svelte-… container) visible. 3. Bluish perception on Vocal mode pills. The pill backgrounds were SURFACE_STRONG (#000) unselected / SURFACE_RAISED (#…aac47cf -
fix(ui): full Brutalist Mono retheme — IBM Plex, padding crush, scoped selectors
Unverified signatureSix issues from the user's manual mobile test: 1. Bluish background tint despite earlier --neutral-* override. Cause: Gradio applies its CSS in multiple :root/.dark contexts. Solution: override the neutral scale + body/block/input fill custom properties under :root, html.dark, .gradio-container, .gradio-container.dark AND .gradio-container .dark (all five contexts). 2. Huge ~60 px horizontal margins on the 360 px viewport. Cause: .gradio-container > .app ships with padding: 16px 32px. Override to 16px 20px on desktop and 8px 10px on mobile so the form actually uses the available width. 3. Field labels rendering at 14 px (~24 visual px on phone) with default Inter. Replace Inter with IBM Plex Sans (body) + IBM Plex Mono (labels, status, metadata) — both via Google Fonts, both distinctive enough to escape generic AI-slop aesthetics per the frontend-design discipline. Shrink labels to 10 px desktop / 9 px mobile, uppercase tracked mono, muted ink. 4…2d0e666 -
fix(ui): wireframe-fidelity polish — neutral palette, mobile single-row, tight chrome
Unverified signatureThree problems the user surfaced after manual testing: 1. The rendered UI had a bluish-grey tint that the wireframes do not. Root cause: gr.themes.colors.gray maps to Tailwind slate-* not true neutral — --neutral-900 is #111827, --neutral-950 is #0b0f19, both visibly cool on phone displays. Override the --neutral-* scale at :root with real neutral hex values (#141414 / #0A0A0A), plus pin the background / block / input fill custom properties to the Brutalist Mono palette via !important to defeat Gradio's defaults. 2. Mobile tab strip wrapped to two rows because each radio label still had width:100% from desktop AND the flex container had no nowrap directive. Add flex-wrap:nowrap to the strip + give each label a proper pill background (border + bg + radius) so they read as tabs instead of plain text. Hide scrollbar but keep horizontal scroll. 3. Inputs / textareas / number fields used Gradio defaults which felt soft compared to the wireframe's crisp Br…5ae7d55