Views
No views yet

| モデル名 | サイズ | 特徴 | 推奨用途 |
|---|---|---|---|
| VoiceCore-BF16.gguf | 6.61 GB | 最高品質、元モデルと同等の精度 | 高品質が必要な場合 |
| VoiceCore-Q4_K-f16.gguf | 2.66 GB | バランス型、実用的な精度 | 通常使用(要注意) |
[ユーザー入力]
↓
[llama.cpp サーバー]
↓
[VoiceCore GGUF]
↓
[音声トークン生成]
↓
[SNACデコーダー]
↓
[音声ファイル/リアルタイム再生]1# Homebrewのインストール(まだの場合)
2/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
3
4# 必要なパッケージのインストール
5brew install cmake
6brew install python@3.11
7
8# Pythonライブラリのインストール
9pip3 install torch snac numpy httpx pyaudio scipy1# llama.cppのクローン
2git clone https://github.com/ggerganov/llama.cpp
3cd llama.cpp
4
5# ビルド(Macの場合)
6make
7
8# Metal(Mac GPU)を使用する場合
9make LLAMA_METAL=11# 基本的な起動方法
2./llama-server \
3 -m path/to/VoiceCore-BF16.gguf \
4 --prio 3 \
5 -c 2048 \
6 -e \
7 -n -2 \
8 -fa \
9 -ngl 99 \
10 -v \
11 --port 8080 \
12 --host 0.0.0.0 \
13 --no-webui
14nglはgpu環境でgpuメモリに収まる範囲で指定
15faはフラッシュアテンション有りでコンパイルした時に指定
16
17# Macでメタル(GPU)を使用する場合
18./llama-server \
19 -m path/to/VoiceCore-BF16.gguf \
20 --prio 3 \
21 -c 2048 \
22 -e \
23 -n -2 \
24 -fa \
25 -ngl 1 \ # Macの場合は1を推奨
26 -v \
27 --port 8080 \
28 --host 0.0.0.0 \
29 --no-webui1import asyncio
2import httpx
3import json
4import re
5import torch
6from snac import SNAC
7import scipy.io.wavfile as wavfile
8import numpy as np
9
10async def generate_voice(prompt, output_file="output.wav"):
11 """シンプルな音声生成関数"""
12
13 # SNACモデルの読み込み
14 print("SNACモデルを読み込んでいます...")
15 snac_model = SNAC.from_pretrained("hubertsiuzdak/snac_24khz")
16 snac_model.to("cpu")
17
18 # サーバーにリクエスト送信
19 payload = {
20 "prompt": prompt,
21 "temperature": 0.8,
22 "top_p": 0.95,
23 "n_predict": 2048,
24 "repeat_penalty": 1.1,
25 "repeat_last_n": 70
26 }
27
28 collected_tokens = []
29
30 async with httpx.AsyncClient(timeout=None) as client:
31 response = await client.post(
32 "http://localhost:8080/completion",
33 json=payload,
34 headers={"Accept": "application/x-ndjson"}
35 )
36
37 # トークンの収集
38 async for line in response.aiter_text():
39 if line.strip():
40 try:
41 data = json.loads(line)
42 if "content" in data:
43 matches = re.findall(r'<custom_token_(\d+)>', data["content"])
44 for match in matches:
45 token_id = 128256 + int(match)
46 collected_tokens.append(token_id)
47 except:
48 pass
49
50 # 音声の生成
51 if collected_tokens:
52 # 7の倍数に調整
53 code_length = (len(collected_tokens) // 7) * 7
54 tokens = collected_tokens[:code_length]
55
56 # コードの再分配
57 codes = redistribute_codes(tokens)
58
59 # 音声デコード
60 with torch.inference_mode():
61 audio_hat = snac_model.decode(codes)
62
63 audio_np = audio_hat.detach().squeeze().cpu().numpy()
64
65 # WAVファイルとして保存
66 wavfile.write(output_file, 24000, audio_np)
67 print(f"音声を {output_file} に保存しました。")
68
69def redistribute_codes(tokens):
70 """トークンをSNACコード形式に変換"""
71 code_list = [t - 128266 for t in tokens]
72
73 layer_1, layer_2, layer_3 = [], [], []
74
75 for i in range(len(code_list) // 7):
76 layer_1.append(code_list[7*i])
77 layer_2.append(code_list[7*i+1]-4096)
78 layer_3.append(code_list[7*i+2]-(2*4096))
79 layer_3.append(code_list[7*i+3]-(3*4096))
80 layer_2.append(code_list[7*i+4]-(4*4096))
81 layer_3.append(code_list[7*i+5]-(5*4096))
82 layer_3.append(code_list[7*i+6]-(6*4096))
83
84 return [
85 torch.tensor(layer_1).unsqueeze(0),
86 torch.tensor(layer_2).unsqueeze(0),
87 torch.tensor(layer_3).unsqueeze(0)
88 ]
89
90# 使用例
91async def main():
92 # 松風さんの声で挨拶
93 prompt = "<custom_token_3><|begin_of_text|>matsukaze_male[neutral]: こんにちは!よろしくお願いします!<|eot_id|><custom_token_4><custom_token_5><custom_token_1>"
94 await generate_voice(prompt, "greeting.wav")
95
96if __name__ == "__main__":
97 asyncio.run(main())pip install llama-cpp-python-nglパラメータを調整してください