SWAG456 commited on
Commit
84de4e6
·
verified ·
1 Parent(s): c2606de

Upload voxcpm2_vps.py

Browse files
Files changed (1) hide show
  1. voxcpm2_vps.py +79 -20
voxcpm2_vps.py CHANGED
@@ -6,13 +6,14 @@ Optimized for: Hostinger KVM 4 (4 vCPU, 8GB RAM) or similar VPS
6
  ⚠️ MEMORY WARNING: VoxCPM2 (2B params) needs ~8-9GB RAM in float32 on CPU.
7
  An 8GB VPS will need swap space. This script auto-checks and warns.
8
 
9
- If OOM persists, the script auto-falls back to VoxCPM-0.5B (much smaller).
10
 
11
  Features:
12
  - Auto memory check with swap creation guide
13
  - Auto float32 conversion for CPU (fixes bfloat16 crash)
14
- - Graceful fallback to VoxCPM-0.5B if RAM is insufficient
15
  - All capabilities: TTS, Voice Design, Voice Cloning, Multilingual, Streaming
 
 
16
  """
17
 
18
  import os
@@ -20,7 +21,6 @@ import sys
20
  import time
21
  import argparse
22
  import warnings
23
- import subprocess
24
 
25
  warnings.filterwarnings("ignore")
26
 
@@ -61,21 +61,6 @@ def check_memory():
61
  return True
62
 
63
 
64
- def create_swap_guide():
65
- """Print swap creation commands."""
66
- print("""
67
- ╔══════════════════════════════════════════════════════════════════╗
68
- ║ HOW TO ADD SWAP ON YOUR VPS (run these via SSH) ║
69
- ╠══════════════════════════════════════════════════════════════════╣
70
- ║ sudo fallocate -l 8G /swapfile ║
71
- ║ sudo chmod 600 /swapfile ║
72
- ║ sudo mkswap /swapfile ║
73
- ║ sudo swapon /swapfile ║
74
- ║ echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab ║
75
- ╚══════════════════════════════════════════════════════════════════╝
76
- """)
77
-
78
-
79
  def load_model(model_id="openbmb/VoxCPM2"):
80
  """Load VoxCPM model optimized for VPS CPU."""
81
  from voxcpm import VoxCPM
@@ -177,10 +162,55 @@ def generate_multilingual(model, texts_dict, timesteps=10):
177
  return results
178
 
179
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
  def run_all_demos(model_id="openbmb/VoxCPM2"):
181
  mem_ok = check_memory()
182
  if not mem_ok:
183
- create_swap_guide()
184
  response = input("\nContinue anyway? (y/n): ").strip().lower()
185
  if response != 'y':
186
  print("[INFO] Exiting. Add swap or use --model openbmb/VoxCPM-0.5B")
@@ -192,10 +222,14 @@ def run_all_demos(model_id="openbmb/VoxCPM2"):
192
  print("RUNNING ALL CAPABILITY DEMOS")
193
  print("=" * 60)
194
 
 
195
  generate_basic_tts(model, "Hello! This is VoxCPM2 running on a VPS.", "demo_01_basic.wav", 10)
 
 
196
  generate_voice_design(model, "A warm professional female narrator",
197
  "Welcome to today's presentation.", "demo_02_design.wav", 12)
198
 
 
199
  texts = {
200
  "english": "The quick brown fox jumps over the lazy dog.",
201
  "chinese": "你好,这是VoxCPM2语音合成模型。",
@@ -203,11 +237,23 @@ def run_all_demos(model_id="openbmb/VoxCPM2"):
203
  }
204
  generate_multilingual(model, texts, 10)
205
 
 
206
  if os.path.exists("my_voice.wav"):
207
  generate_voice_clone(model, "This is my cloned voice.", "my_voice.wav", "demo_05_clone.wav", 15)
 
 
 
 
 
208
  else:
209
  print("\n[SKIP] Place 'my_voice.wav' to test voice cloning")
210
 
 
 
 
 
 
 
211
  print("\n" + "=" * 60)
212
  print("ALL DEMOS COMPLETE!")
213
  print("=" * 60)
@@ -233,12 +279,18 @@ Examples:
233
 
234
  # Voice clone
235
  python voxcpm2_vps.py --mode clone --text "Hi" --reference my_voice.wav
 
 
 
 
 
 
236
  """
237
  )
238
  parser.add_argument("--model", type=str, default="openbmb/VoxCPM2",
239
  help="Model ID: openbmb/VoxCPM2 (2B) or openbmb/VoxCPM-0.5B (smaller)")
240
  parser.add_argument("--demo", action="store_true", help="Run all capability demos")
241
- parser.add_argument("--mode", choices=["basic", "design", "clone", "multilingual"],
242
  default="basic", help="Generation mode")
243
  parser.add_argument("--text", type=str, default="Hello from VoxCPM2 on VPS!", help="Text to synthesize")
244
  parser.add_argument("--description", type=str, default="A warm professional voice", help="Voice design description")
@@ -274,6 +326,13 @@ Examples:
274
  "spanish": "¡Hola! Esta es síntesis de voz.",
275
  }
276
  generate_multilingual(model, texts, args.timesteps)
 
 
 
 
 
 
 
277
 
278
  print(f"\n[OK] Done! Output: {args.output}")
279
 
 
6
  ⚠️ MEMORY WARNING: VoxCPM2 (2B params) needs ~8-9GB RAM in float32 on CPU.
7
  An 8GB VPS will need swap space. This script auto-checks and warns.
8
 
9
+ If OOM persists, use VoxCPM-0.5B (much smaller).
10
 
11
  Features:
12
  - Auto memory check with swap creation guide
13
  - Auto float32 conversion for CPU (fixes bfloat16 crash)
 
14
  - All capabilities: TTS, Voice Design, Voice Cloning, Multilingual, Streaming
15
+ - NEW: Multilingual Voice Cloning (clone voice + speak any language)
16
+ - NEW: Multilingual Voice Design (design voice + speak any language)
17
  """
18
 
19
  import os
 
21
  import time
22
  import argparse
23
  import warnings
 
24
 
25
  warnings.filterwarnings("ignore")
26
 
 
61
  return True
62
 
63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  def load_model(model_id="openbmb/VoxCPM2"):
65
  """Load VoxCPM model optimized for VPS CPU."""
66
  from voxcpm import VoxCPM
 
162
  return results
163
 
164
 
165
+ # NEW: Multilingual Voice Cloning — clone a voice and speak ANY language!
166
+ def generate_multilingual_clone(model, text, reference_wav, output_path="output_multi_clone.wav", timesteps=15):
167
+ """Clone a voice and speak in ANY language!"""
168
+ import soundfile as sf
169
+ if not os.path.exists(reference_wav):
170
+ print(f"[ERROR] Reference not found: {reference_wav}")
171
+ return None
172
+
173
+ print(f"\n[MODE] Multilingual Voice Cloning")
174
+ print(f"[TEXT] {text[:80]}...")
175
+ print(f"[REF] {reference_wav}")
176
+ print("[INFO] The cloned voice will speak in whatever language you typed!")
177
+
178
+ start = time.time()
179
+ wav = model.generate(text=text, reference_wav_path=reference_wav, cfg_value=2.0,
180
+ inference_timesteps=timesteps, max_len=4096)
181
+ elapsed = time.time() - start
182
+
183
+ sf.write(output_path, wav, model.tts_model.sample_rate)
184
+ duration = len(wav) / model.tts_model.sample_rate
185
+ print(f"[OK] Saved: {output_path} ({duration:.1f}s audio, {elapsed:.1f}s generation)")
186
+ print("[INFO] ✅ The cloned voice is speaking the language of your text!")
187
+ return output_path
188
+
189
+
190
+ # NEW: Multilingual Voice Design — design a voice and speak ANY language!
191
+ def generate_multilingual_design(model, description, text, output_path="output_multi_design.wav", timesteps=12):
192
+ """Design a voice and speak in ANY language!"""
193
+ import soundfile as sf
194
+ full_text = f"({description}) {text}"
195
+ print(f"\n[MODE] Multilingual Voice Design")
196
+ print(f"[DESC] {description}")
197
+ print(f"[TEXT] {text[:80]}...")
198
+ print("[INFO] The designed voice will speak in whatever language you typed!")
199
+
200
+ start = time.time()
201
+ wav = model.generate(text=full_text, cfg_value=2.0, inference_timesteps=timesteps, max_len=4096)
202
+ elapsed = time.time() - start
203
+
204
+ sf.write(output_path, wav, model.tts_model.sample_rate)
205
+ duration = len(wav) / model.tts_model.sample_rate
206
+ print(f"[OK] Saved: {output_path} ({duration:.1f}s audio, {elapsed:.1f}s generation)")
207
+ print("[INFO] ✅ The designed voice is speaking the language of your text!")
208
+ return output_path
209
+
210
+
211
  def run_all_demos(model_id="openbmb/VoxCPM2"):
212
  mem_ok = check_memory()
213
  if not mem_ok:
 
214
  response = input("\nContinue anyway? (y/n): ").strip().lower()
215
  if response != 'y':
216
  print("[INFO] Exiting. Add swap or use --model openbmb/VoxCPM-0.5B")
 
222
  print("RUNNING ALL CAPABILITY DEMOS")
223
  print("=" * 60)
224
 
225
+ # 1. Basic TTS
226
  generate_basic_tts(model, "Hello! This is VoxCPM2 running on a VPS.", "demo_01_basic.wav", 10)
227
+
228
+ # 2. Voice Design
229
  generate_voice_design(model, "A warm professional female narrator",
230
  "Welcome to today's presentation.", "demo_02_design.wav", 12)
231
 
232
+ # 3. Multilingual
233
  texts = {
234
  "english": "The quick brown fox jumps over the lazy dog.",
235
  "chinese": "你好,这是VoxCPM2语音合成模型。",
 
237
  }
238
  generate_multilingual(model, texts, 10)
239
 
240
+ # 4. Voice Clone (if reference exists)
241
  if os.path.exists("my_voice.wav"):
242
  generate_voice_clone(model, "This is my cloned voice.", "my_voice.wav", "demo_05_clone.wav", 15)
243
+
244
+ # 5. NEW: Multilingual Clone — clone voice, speak Chinese!
245
+ generate_multilingual_clone(model,
246
+ "你好!这是我克隆的声音在说中文。非常自然和流畅!",
247
+ "my_voice.wav", "demo_06_multi_clone.wav", 15)
248
  else:
249
  print("\n[SKIP] Place 'my_voice.wav' to test voice cloning")
250
 
251
+ # 6. NEW: Multilingual Design — design voice, speak Chinese!
252
+ generate_multilingual_design(model,
253
+ "A warm elderly British woman, soft and caring",
254
+ "你好!这是一个温暖的英国老太太的声音在说中文。",
255
+ "demo_07_multi_design.wav", 12)
256
+
257
  print("\n" + "=" * 60)
258
  print("ALL DEMOS COMPLETE!")
259
  print("=" * 60)
 
279
 
280
  # Voice clone
281
  python voxcpm2_vps.py --mode clone --text "Hi" --reference my_voice.wav
282
+
283
+ # Multilingual clone (NEW!) — clone voice + speak any language
284
+ python voxcpm2_vps.py --mode multi-clone --text "你好!" --reference my_voice.wav
285
+
286
+ # Multilingual design (NEW!) — design voice + speak any language
287
+ python voxcpm2_vps.py --mode multi-design --description "warm elderly woman" --text "¡Hola!"
288
  """
289
  )
290
  parser.add_argument("--model", type=str, default="openbmb/VoxCPM2",
291
  help="Model ID: openbmb/VoxCPM2 (2B) or openbmb/VoxCPM-0.5B (smaller)")
292
  parser.add_argument("--demo", action="store_true", help="Run all capability demos")
293
+ parser.add_argument("--mode", choices=["basic", "design", "clone", "multilingual", "multi-clone", "multi-design"],
294
  default="basic", help="Generation mode")
295
  parser.add_argument("--text", type=str, default="Hello from VoxCPM2 on VPS!", help="Text to synthesize")
296
  parser.add_argument("--description", type=str, default="A warm professional voice", help="Voice design description")
 
326
  "spanish": "¡Hola! Esta es síntesis de voz.",
327
  }
328
  generate_multilingual(model, texts, args.timesteps)
329
+ elif args.mode == "multi-clone":
330
+ if not args.reference:
331
+ print("[ERROR] --reference required for multi-clone mode")
332
+ sys.exit(1)
333
+ generate_multilingual_clone(model, args.text, args.reference, args.output, args.timesteps)
334
+ elif args.mode == "multi-design":
335
+ generate_multilingual_design(model, args.description, args.text, args.output, args.timesteps)
336
 
337
  print(f"\n[OK] Done! Output: {args.output}")
338