jempf Cursor commited on
Commit
ca99e8a
·
1 Parent(s): 6ece6c9

ZeroGPU attempt: boot-safe loader + @spaces.GPU realtime handler.

Browse files

- peitho_model.py: load base + overlay German v6 with NO import-time CUDA
warmup (warmup crashes ZeroGPU on boot, which has no GPU until a
@spaces.GPU call). Import spaces first so CUDA placement is deferred.
- app.py: load via peitho_model instead of liquid_audio.demo.model.
- chat.py: import from peitho_model; wrap the FastRTC streaming handler in
@spaces.GPU so the whole generation runs in one GPU-scoped slice.
- requirements: add spaces.

Experimental: realtime FastRTC on ZeroGPU is unverified locally; validate
on the live build with hardware set to ZeroGPU.

Co-authored-by: Cursor <cursoragent@cursor.com>

Files changed (4) hide show
  1. app.py +9 -25
  2. chat.py +5 -1
  3. peitho_model.py +37 -0
  4. requirements.txt +1 -0
app.py CHANGED
@@ -1,45 +1,29 @@
1
- """HF Spaces entry point: Peitho 1.5B v6 chat demo.
2
 
3
  Background: the stock LFM2.5-Audio-1.5B base model is English-only for
4
  speech-to-speech (see https://huggingface.co/LiquidAI/LFM2.5-Audio-1.5B —
5
- "Supported languages: English"). Our v5/v6 fine-tunes are what teach it
6
- German audio output. A short A/B with the unmodified base model produced
7
- garbled German + robotic audio — confirming the fine-tune is essential.
8
 
9
- This file loads stock LFM2.5-Audio-1.5B via `liquid_audio.demo.model`, then
10
- overlays the v6 fine-tune weights from `jempf/peitho-1.5b-v6` on top.
 
11
  """
12
  from __future__ import annotations
13
 
14
  import sys
15
  from pathlib import Path
16
 
17
- from accelerate import load_checkpoint_in_model
18
- from huggingface_hub import snapshot_download
19
-
20
  sys.path.insert(0, str(Path(__file__).parent))
21
 
22
- PEITHO_REPO = "jempf/peitho-1.5b-v6"
23
-
24
 
25
  def main() -> None:
26
- print(f"Downloading Peitho v6 weights from {PEITHO_REPO}...")
27
- weights_dir = snapshot_download(
28
- repo_id=PEITHO_REPO,
29
- allow_patterns=["model.safetensors", "config.json"],
30
- )
31
- print(f"Weights cached at {weights_dir}")
32
-
33
- print("Loading base LFM2.5-Audio-1.5B...")
34
- import liquid_audio.demo.model as model_mod
35
-
36
- print(f"Overlaying v6 weights onto base model...")
37
- load_checkpoint_in_model(model_mod.lfm2_audio, weights_dir)
38
- model_mod.lfm2_audio.eval()
39
- print("v6 ready.")
40
 
41
  print("Importing chat demo and launching...")
42
  import chat as chat_mod
 
43
  chat_mod.demo.launch()
44
 
45
 
 
1
+ """HF Spaces (ZeroGPU) entry point: Peitho 1.5B v6 German voice demo.
2
 
3
  Background: the stock LFM2.5-Audio-1.5B base model is English-only for
4
  speech-to-speech (see https://huggingface.co/LiquidAI/LFM2.5-Audio-1.5B —
5
+ "Supported languages: English"). Our v6 fine-tune is what teaches it German
6
+ audio output. A short A/B with the unmodified base model produced garbled
7
+ German + robotic audio — confirming the fine-tune is essential.
8
 
9
+ Model loading + the German v6 overlay live in `peitho_model.py`, which is
10
+ written to be boot-safe on ZeroGPU (no CUDA warmup at import). This entry
11
+ point just imports the model, then launches the chat demo.
12
  """
13
  from __future__ import annotations
14
 
15
  import sys
16
  from pathlib import Path
17
 
 
 
 
18
  sys.path.insert(0, str(Path(__file__).parent))
19
 
 
 
20
 
21
  def main() -> None:
22
+ import peitho_model # noqa: F401 # triggers load + v6 overlay (boot-safe)
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
  print("Importing chat demo and launching...")
25
  import chat as chat_mod
26
+
27
  chat_mod.demo.launch()
28
 
29
 
chat.py CHANGED
@@ -21,6 +21,7 @@ from queue import Queue
21
  from threading import Thread
22
  from typing import Any
23
 
 
24
  import gradio as gr
25
  import httpx
26
  import numpy as np
@@ -39,7 +40,9 @@ from briefing import (
39
  format_schedule_html,
40
  )
41
  from liquid_audio import ChatState, LFMModality
42
- from liquid_audio.demo.model import lfm2_audio, mimi, proc
 
 
43
 
44
  AUDIO_EOS_TOKEN = 2048
45
  TURN_TTL_SECONDS = 600
@@ -143,6 +146,7 @@ def chat_producer(
143
  q.put(None)
144
 
145
 
 
146
  def chat_response(
147
  audio: tuple[int, np.ndarray],
148
  _id: str,
 
21
  from threading import Thread
22
  from typing import Any
23
 
24
+ import spaces
25
  import gradio as gr
26
  import httpx
27
  import numpy as np
 
40
  format_schedule_html,
41
  )
42
  from liquid_audio import ChatState, LFMModality
43
+ from peitho_model import lfm2_audio, mimi, proc
44
+
45
+ GPU_DURATION_SECONDS = 120
46
 
47
  AUDIO_EOS_TOKEN = 2048
48
  TURN_TTL_SECONDS = 600
 
146
  q.put(None)
147
 
148
 
149
+ @spaces.GPU(duration=GPU_DURATION_SECONDS)
150
  def chat_response(
151
  audio: tuple[int, np.ndarray],
152
  _id: str,
peitho_model.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Boot-safe Peitho model loader for ZeroGPU.
2
+
3
+ Unlike `liquid_audio.demo.model`, this module does NOT run a CUDA warmup at
4
+ import time. On ZeroGPU there is no GPU outside an `@spaces.GPU` call, so any
5
+ eager CUDA op at import would crash the Space on boot. We import `spaces`
6
+ first (which patches torch so `.to("cuda")` is deferred until a GPU is
7
+ actually allocated), load the base model, overlay the German v6 fine-tune,
8
+ and request the CUDA placement — the real transfer happens lazily inside the
9
+ first GPU-scoped call.
10
+ """
11
+ from __future__ import annotations
12
+
13
+ import spaces # noqa: F401 # must precede torch CUDA usage to enable ZeroGPU
14
+ import torch
15
+ from accelerate import load_checkpoint_in_model
16
+ from huggingface_hub import snapshot_download
17
+ from liquid_audio import LFM2AudioModel, LFM2AudioProcessor
18
+
19
+ BASE_REPO: str = "LiquidAI/LFM2.5-Audio-1.5B"
20
+ PEITHO_REPO: str = "jempf/peitho-1.5b-v6"
21
+
22
+ print("Loading processor + base LFM2.5-Audio-1.5B (no CUDA warmup)...")
23
+ proc = LFM2AudioProcessor.from_pretrained(BASE_REPO).eval()
24
+ lfm2_audio = LFM2AudioModel.from_pretrained(BASE_REPO).eval()
25
+ mimi = proc.mimi.eval()
26
+
27
+ print(f"Overlaying German v6 weights from {PEITHO_REPO}...")
28
+ _weights_dir = snapshot_download(
29
+ repo_id=PEITHO_REPO,
30
+ allow_patterns=["model.safetensors", "config.json"],
31
+ )
32
+ load_checkpoint_in_model(lfm2_audio, _weights_dir)
33
+ lfm2_audio.eval()
34
+
35
+ lfm2_audio.to("cuda")
36
+ mimi.to("cuda")
37
+ print("Peitho v6 ready (CUDA placement deferred until first GPU call).")
requirements.txt CHANGED
@@ -3,3 +3,4 @@ fastrtc[vad]>=0.0.30
3
  accelerate>=1.0.0
4
  huggingface_hub>=0.27.0
5
  httpx>=0.27.0
 
 
3
  accelerate>=1.0.0
4
  huggingface_hub>=0.27.0
5
  httpx>=0.27.0
6
+ spaces>=0.30.0