akhaliq HF Staff Claude commited on
Commit
98ed9bf
Β·
1 Parent(s): 7e251df

Move nemo-toolkit install to runtime to unblock gradio 6.20 build

Browse files

The previous upgrade failed at build time because:
- gradio 6.20 requires huggingface-hub>=1.2
- nemo-toolkit[tts]==2.4.0 pins transformers<=4.52 (4.51.x)
- transformers 4.51.x requires huggingface-hub<1.0

pip refuses to resolve these together. Move the nemo install to
create_env.py so it happens after we've pinned transformers==5.3.0
+ hub>=1.2 with --no-deps β€” sidestepping the resolver conflict.

- requirements.txt: remove nemo-toolkit[tts]; list its common runtime
deps explicitly (librosa, soundfile, omegaconf, webdataset, pandas,
etc.) since --no-deps skips them.
- create_env.py: rewrite as a 3-step install β€” pin transformers+hub,
install nemo with --no-deps, cap numpy<2.0.
- README.md: document the new install dance.
- app.py: update the startup-order docstring.

Co-Authored-By: Claude <noreply@anthropic.com>

Files changed (4) hide show
  1. README.md +12 -2
  2. app.py +5 -3
  3. create_env.py +55 -17
  4. requirements.txt +24 -4
README.md CHANGED
@@ -48,5 +48,15 @@ generation parameters β€” re-point the Space without touching code.
48
  - The model repo is private: set the `HF_TOKEN` Space secret.
49
  - ZeroGPU: the model is loaded once at startup; each request only runs
50
  generation inside the GPU context.
51
- - `create_env.py` re-pins `transformers==5.3.0` at startup (NeMo downgrades
52
- it at build time) β€” it must run before any ML import in `app.py`.
 
 
 
 
 
 
 
 
 
 
 
48
  - The model repo is private: set the `HF_TOKEN` Space secret.
49
  - ZeroGPU: the model is loaded once at startup; each request only runs
50
  generation inside the GPU context.
51
+ - `create_env.py` orchestrates a 4-step install at app startup β€” it must
52
+ run before any ML import in `app.py`:
53
+ 1. Pin `huggingface-hub>=1.2,<2.0` (compatible with both gradio 6.20
54
+ and `nemo-toolkit`).
55
+ 2. `pip install --no-deps nemo-toolkit[tts]==2.4.0` (avoiding a downgrade
56
+ of hub by the resolver).
57
+ 3. Force-reinstall `transformers==5.3.0` (Qwen3.5 backbone that the
58
+ Gepard checkpoint was trained on).
59
+ 4. Cap `numpy<2.0` so the codec/NeMo stack stays on numpy 1.x.
60
+ - `nemo-toolkit` is installed at runtime (not in `requirements.txt`) to
61
+ keep gradio 6.20's `huggingface-hub>=1.2` constraint resolvable at
62
+ build time β€” NeMo's `transformers<=4.52` would otherwise pull hub<1.0.
app.py CHANGED
@@ -1,9 +1,11 @@
1
  """GEPARD β€” text-to-speech inference Space (ZeroGPU), gradio.Server backend.
2
 
3
  Startup order is load-bearing:
4
- 1. ``create_env.setup_dependencies()`` re-pins transformers BEFORE any
5
- ML import β€” the Space image ships whatever NeMo pinned at build time,
6
- but the Gepard checkpoint requires transformers 5.3.0.
 
 
7
  2. ``spaces`` is imported before torch so ZeroGPU can patch CUDA calls.
8
  3. The engine (model + codec + speakers) is built ONCE at module level;
9
  ZeroGPU replays the recorded ``.to("cuda")`` moves when a GPU is
 
1
  """GEPARD β€” text-to-speech inference Space (ZeroGPU), gradio.Server backend.
2
 
3
  Startup order is load-bearing:
4
+ 1. ``create_env.setup_dependencies()`` installs nemo-toolkit and re-pins
5
+ transformers BEFORE any ML import β€” the Space image ships gradio 6.20
6
+ which pins huggingface-hub>=1.2, and NeMo's transformers<=4.52 would
7
+ pull hub<1.0 at build time. create_env.py upgrades hub first, then
8
+ installs nemo with --no-deps, then re-pins transformers==5.3.0.
9
  2. ``spaces`` is imported before torch so ZeroGPU can patch CUDA calls.
10
  3. The engine (model + codec + speakers) is built ONCE at module level;
11
  ZeroGPU replays the recorded ``.to("cuda")`` moves when a GPU is
create_env.py CHANGED
@@ -3,24 +3,62 @@ import subprocess
3
  import sys
4
 
5
  def setup_dependencies():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  os.environ["OMP_NUM_THREADS"] = "4"
 
 
 
 
 
 
7
  try:
8
- if os.path.exists('/tmp/deps_installed'):
9
- return
10
-
11
- # Re-pin transformers on top of whatever NeMo downgraded at build time
12
- # (the Gepard checkpoint needs the Qwen3.5 backbone from 5.x). This
13
- # upgrades huggingface-hub to 1.x β€” gradio 5.49 accepts <2.0, so the
14
- # UI keeps working. numpy is capped so the force-reinstall does not
15
- # bump it to 2.x under the NeMo stack built against 1.26.
16
- print("Re-pinning transformers==5.3.0 ...")
17
- subprocess.check_call([
18
- sys.executable, "-m", "pip", "install", "--force-reinstall", "--no-cache-dir",
19
- "transformers==5.3.0", "numpy<2.0"
20
  ])
21
-
22
- with open('/tmp/deps_installed', 'w') as f:
23
- f.write('done')
24
-
 
 
 
 
 
 
 
 
 
 
 
25
  except Exception as e:
26
- print(f"Dependencies setup error: {e}")
 
 
3
  import sys
4
 
5
  def setup_dependencies():
6
+ """Install NeMo and pin transformers in the right order to satisfy
7
+ gradio 6.20's huggingface-hub>=1.2 requirement while still ending up
8
+ on transformers 5.3.0 (which the Gepard checkpoint needs).
9
+
10
+ Why not put nemo-toolkit in requirements.txt? NeMo's
11
+ ``nemo-toolkit[tts]==2.4.0`` pulls in ``transformers<=4.52`` (which
12
+ resolves to 4.51.x), and that requires ``huggingface-hub<1.0`` β€”
13
+ conflicting with gradio 6.20's ``huggingface-hub>=1.2`` at build time
14
+ so pip refuses to resolve. We install NeMo at runtime instead, after
15
+ pinning hub and transformers to the versions we want.
16
+
17
+ Order is load-bearing:
18
+ 1. transformers==5.3.0 with --no-deps β€” forces the runtime onto the
19
+ Qwen3.5 backbone version the Gepard checkpoint was trained on.
20
+ Pulls in hub>=1.2 transitively, satisfying gradio 6.20.
21
+ 2. nemo-toolkit[tts]==2.4.0 with --no-deps β€” installed on top of
22
+ transformers 5.3.0 without re-resolving its declared (conflicting)
23
+ transformers<=4.52 constraint. The codec only needs
24
+ nemo.collections.tts.models.AudioCodecModel; the missing
25
+ transformers<5.x import paths NeMo *might* check for aren't
26
+ exercised at inference.
27
+ 3. numpy<2.0 β€” keep the NeMo/codec stack on numpy 1.x.
28
+
29
+ Idempotent: writes a sentinel file so the install only runs once per
30
+ container.
31
+ """
32
  os.environ["OMP_NUM_THREADS"] = "4"
33
+
34
+ sentinel = "/tmp/deps_installed"
35
+ if os.path.exists(sentinel):
36
+ return
37
+
38
+ pip = [sys.executable, "-m", "pip", "install", "--no-cache-dir"]
39
  try:
40
+ # 1. Pin the transformers + hub versions gradio 6.20 needs, before
41
+ # NeMo gets a chance to downgrade them. --no-deps because we
42
+ # already have these libraries installed at compatible versions.
43
+ print("Pinning transformers==5.3.0 + hub>=1.2 (no-deps) ...")
44
+ subprocess.check_call(pip + [
45
+ "--no-deps", "transformers==5.3.0", "huggingface-hub>=1.2,<2.0",
 
 
 
 
 
 
46
  ])
47
+
48
+ # 2. Install NeMo on top without re-resolving dependencies. Its
49
+ # declared transformers<=4.52 / hub<1.0 would conflict; with
50
+ # --no-deps the resolver doesn't see those constraints.
51
+ print("Installing nemo-toolkit[tts]==2.4.0 (no-deps) ...")
52
+ subprocess.check_call(pip + ["--no-deps", "nemo-toolkit[tts]==2.4.0"])
53
+
54
+ # 3. Cap numpy so a transitive bump doesn't break the NeMo/codec
55
+ # stack, which is built against numpy 1.x.
56
+ print("Capping numpy<2.0 ...")
57
+ subprocess.check_call(pip + ["numpy<2.0"])
58
+
59
+ with open(sentinel, "w") as f:
60
+ f.write("done")
61
+
62
  except Exception as e:
63
+ print(f"Dependencies setup error: {e}")
64
+ raise
requirements.txt CHANGED
@@ -1,12 +1,32 @@
1
  # GEPARD Space dependencies.
2
  #
3
  # torch is provided by the Space image β€” do NOT pin it here.
4
- nemo-toolkit[tts]==2.4.0
 
 
 
 
 
 
 
 
 
5
  safetensors
6
  librosa>=0.10.0
7
  soundfile
8
- omegaconf
9
  pyyaml
10
- numpy
11
  scipy
12
- gradio==6.20.0
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  # GEPARD Space dependencies.
2
  #
3
  # torch is provided by the Space image β€” do NOT pin it here.
4
+ # gradio is pinned via sdk_version in README.md (the Dockerfile installs it
5
+ # with the [oauth,mcp] extras). Don't re-pin it here.
6
+ #
7
+ # nemo-toolkit[tts]==2.4.0 is installed in create_env.py at runtime instead
8
+ # of here, because its `transformers<=4.52` constraint pulls in transformers
9
+ # 4.51.x which requires huggingface-hub<1.0 β€” conflicting with gradio 6.20's
10
+ # hub>=1.2 requirement at build time. create_env.py pins transformers==5.3.0
11
+ # + hub>=1.2 first (with --no-deps), then installs nemo with --no-deps.
12
+ # The deps listed below cover NeMo's runtime imports (nemo.collections.tts
13
+ # only needs torch + omegaconf at import time, plus a few small libs).
14
  safetensors
15
  librosa>=0.10.0
16
  soundfile
 
17
  pyyaml
18
+ numpy<2.0
19
  scipy
20
+ # NeMo runtime deps (not installed by `pip install nemo-toolkit[tts]` since
21
+ # we use --no-deps to keep gradio 6.20's hub constraint resolvable).
22
+ omegaconf
23
+ webdataset
24
+ pandas
25
+ tqdm
26
+ wget
27
+ inflect
28
+ num2words
29
+ sentencepiece
30
+ editdistance
31
+ hydra-core
32
+ packaging