モデル概要
モデル特徴
モデル能力
使用事例
🚀 Hypa_Orpheus-3b-0.1-ft (merged 16-bit)
このモデルは、canopylabs/orpheus-3b-0.1-ft
を16ビット量子化し、マージしたメモリ効率の良い微調整バージョンです。UnslothとLoRAを用いて最適化され、特に低リソースのアフリカ言語における表現力豊かな多言語テキスト読み上げ(TTS)に最適化されています。以下の機能を提供します。
- テキスト読み上げ生成
- 代表されにくいアクセントの音声合成
- 声のクローニングと感情合成
- 多言語低リソース音声AIの研究
🚀 クイックスタート
このモデルの使用方法については、「Usage」セクションを参照してください。
✨ 主な機能
- 多言語のテキスト読み上げ生成が可能で、特に低リソースのアフリカ言語に対応。
- 代表されにくいアクセントの音声合成が可能。
- 声のクローニングと感情合成機能を備える。
- 多言語低リソース音声AIの研究に役立つ。
📚 ドキュメント
モデルの詳細
モデル概要
このモデルは、ナイジェリアアクセントと低リソース言語(イボ語、ヨルバ語、ハウサ語)の音声を含む、合計300時間以上(75,000サンプル)の並列テキスト音声データセットで学習されました。データセットの重要な一部は、AfroVoicesによる実世界のYouTubeデータの文字起こし(Random speaker、約100時間以上)から得られています。 多言語能力を維持・強化し、災害的忘却を避けるために、元の8つのOrpheus音声からデフォルトの感情プロンプトを使用してサンプリングされた合成音声テキストデータも含まれています。 最終的な学習セットには、以下のような新しい話者も含まれています。
- Eniola(40時間) – 女性、大胆で明瞭な声
- Moyo(40時間) – 女性、プロフェッショナルで分かりやすい声
- Lovelyn(35時間) – 女性、暖かく内気な声
- Precious(30時間) – 女性、友好的で穏やかな声
このモデルは、アフリカ言語における低リソース多言語TTSタスクで最先端の性能を発揮しています(以下の学習統計を参照)。
ベースモデルの詳細
Canopy Labs
がリリースしたデフォルトのOrpheus-TTSモデルは、以下の音声と感情をサポートしています。
音声: tara
, leah
, jess
, leo
, dan
, mia
, zac
, zoe
。
感情: <laugh>
, <chuckle>
, <sigh>
, <cough>
, <sniffle>
, <groan>
, <yawn>
, <gasp>
。
合成データの生成と追加により、この微調整モデルもこれらの音声と感情を維持しています。音声と感情の詳細については、デフォルトモデルのカードを参照してください。
モデルのサンプル生成
🎧 Hypa Orpheus-TTSによって生成されたサンプルを聴くことができます。
テキスト入力 | 音声出力 | 言語 | 音声 |
---|---|---|---|
I am cooking for guests tomorrow and need to know how to make aioli. Can you give me a step-by-step recipe. | 英語 | Emmanuel | |
Ina dafa abinci don bakin gobe kuma ina bukatar sanin yadda ake yin ailoli. Za ka iya ba ni girke-gireken matakan daya bayan daya? | ハウサ語 | Emmanuel | |
Ina dafa abinci don bakin gobe kuma ina bukatar sanin yadda ake yin ailoli. Za ka iya ba ni girke-gireken matakan daya bayan daya? | ハウサ語 | Eniola | |
Èmi máa se oúnjẹ fún àwọn àlejò l'ọ́la mo sì nílò láti mọ bí wọn ti ńṣe aioli. Ṣe o lè fún mi ni àwọn ìlànà ìdáná ẹlẹ́sẹẹsẹ? | ヨルバ語 | Eniola | |
I am cooking for guests tomorrow and need to know how to make aioli. Can you give me a step-by-step recipe. | 英語 | Eniola | |
M na-esi nri maka ndị ọbịa echi ma achọ ịmata otú esi esi aioli. Ị nwere ike inye m usoro ntụziaka? | イボ語 | Eniola | |
M na-esi nri maka ndị ọbịa echi ma achọ ịmata otú esi esi aioli. Ị nwere ike inye m usoro ntụziaka? | イボ語 | Lovelyn | |
I am cooking for guests tomorrow and need to know how to make aioli. Can you give me a step-by-step recipe. | 英語 | Lovelyn |
学習の詳細
学習概要
- ベースモデル: canopylabs/orpheus-3b-0.1-ft
- 学習エンジン: Unsloth + LoRA
- LoRA設定: r=1024, alpha=1024, dropout=0.0, full attention + FFN adaptation
- 量子化: 学習時は4ビット(bnb)、最終モデルはメモリ効率が高い
- 総ステップ数: 18,014(1エポック)
- バッチサイズ: 1 × 4(勾配累積)
- GPU: A100 40GB(最大55%のVRAM使用)
ステップ | 学習損失 | 検証損失 |
---|---|---|
5,000 | 3.9496 | 3.8790 |
10,000 | 3.8863 | 3.79497 |
15,000 | 3.8544 | 3.75323 |
データセット概要
- データソース:
- ✅ 手動でアラインされたYouTubeの文字起こし(Random)
- ✅ Orpheus TTSからの合成音声生成
- ✅ アフリカ英語、イボ語、ヨルバ語、ハウサ語の並列テキスト音声ペア
- 総時間: 300時間以上(複数アクセント)
- 主要な話者: 45種類以上のユニークな音声(下の話者分布チャートを参照)
Hypa_Fleurs イニシアチブと同様に、近日中に完全なデータセットをオープンソース化する予定です。
ライセンスと引用
このモデルは オープンソースライセンス(Apache-2.0)の下でリリースされています。詳細については、LICENSEファイルを参照してください。
このモデルをあなたの研究で使用する場合は、このモデルとベースのcanopylabs/orpheus-3b-0.1-ft
モデルの両方を次のように引用してください。
@misc{canopylabsorpheus,
title={Orpheus-3b-0.1-ft: A Multilingual Text-to-Speech Model},
author={Canopy Labs},
year={2025},
publisher={Hugging Face},
howpublished={\url{https://huggingface.co/canopylabs/orpheus-3b-0.1-ft}},
note={Fine-tuned version of Orpheus for expressive TTS}
}
@misc{hypaorpheus4bit,
title={Hypa_Orpheus-3b-0.1-ft (LoRA-4bit)},
author={Hypa AI},
year={2025},
note={Fine-tuned Orpheus TTS on African languages},
url={https://huggingface.co/hypaai/Hypa_Orpheus-3b-0.1-ft-unsloth-bnb-4bit}
}
謝辞
- Canopy Labsチーム: 基礎モデルを作成し、オープンソース化してくれたことに感謝します。
- AfroVoicesの専門家: 翻訳の専門知識と高品質なデータセットを提供してくれたことに感謝します。
- コミュニティの支援: すべての支援者、貢献者、ユーザーに感謝します。
連絡先と貢献
質問、問題、または貢献に関しては、このリポジトリにイシューを作成するか、hypa.ai.ng@gmail.com に連絡してください。貢献は大歓迎です!
閉じる言葉
Hypa_Orpheusを公開することで、アフリカ言語の多言語音声技術の研究と開発を促進したいと考えています。
Hypa AIは、技術的に高度であるだけでなく、文化的にも配慮したインテリジェントなソリューションを開発する使命に固く立ち向かっています。これにより、AIの未来がそのサービス対象となる世界と同じように多様で包括的なものになることを目指しています。
Hypa AIの子会社であるAfroVoicesは、インテリジェンス時代においてアフリカの声、言語、文化を増幅することに専念しています。デジタル表現のギャップを埋めることに焦点を当て、AfroVoicesはアフリカ言語のデータセットとリソースを作成し、AI技術における包括性と文化的理解を促進しています。彼らの使命は技術革新を超えて、アフリカの言語的多様性の豊かさを世界的な舞台で祝福することを目指しています。
💻 使用例
基本的な使用法
Unsloth推論
必要なパッケージをダウンロードします。
%%capture
import os
if "COLAB_" not in "".join(os.environ.keys()):
!pip install unsloth
else:
# Do this only in Colab notebooks! Otherwise use pip install unsloth
!pip install --no-deps bitsandbytes accelerate xformers==0.0.29.post3 peft trl==0.15.2 triton cut_cross_entropy unsloth_zoo
!pip install sentencepiece protobuf datasets huggingface_hub hf_transfer
!pip install --no-deps unsloth
!pip install snac
モデル(SNACエンコーダ/デコーダと微調整されたHypa_Orpheusの両方)をダウンロードします。
import torch
from snac import SNAC
from unsloth import FastLanguageModel
dtype = None # None for auto detection. Float16 for Tesla T4, V100, Bfloat16 for Ampere+
load_in_4bit = True # Use 4bit quantization to reduce memory usage. Can be False.
model, tokenizer = FastLanguageModel.from_pretrained(
model_name = "hypaai/Hypa_Orpheus-3b-0.1-ft-unsloth-merged_16bit",
max_seq_length= 2048, # Choose any for long context!
dtype = dtype,
load_in_4bit = load_in_4bit,
#token = "hf_...", # use one if using gated models like meta-llama/Llama-2-7b-hf
)
snac_model = SNAC.from_pretrained("hubertsiuzdak/snac_24khz")
snac_model = snac_model.to("cuda")
テキストプロンプトを作成し、音声を選択して、モデルに渡します。
prompts = [
"""Mo nífẹ̀ẹ́sí láti ṣe Ph.D sùgbọ́n mi ò ì tíì pinnu ẹ̀ka tí màá ṣe. Àwọn anfaani tí óń dé oríṣiríṣi àwọn olùgbọ́ káàkiri àgbáyé wo ni mo ní""",
]
chosen_voice = "Eniola" # None for single-speaker
FastLanguageModel.for_inference(model) # Enable native 2x faster inference
snac_model.to("cpu")# Moving snac_model cuda to cpu
prompts_ = [(f"{chosen_voice}: " + p) if chosen_voice else p for p in prompts]
all_input_ids = []
for prompt in prompts_:
input_ids = tokenizer(prompt, return_tensors="pt").input_ids
all_input_ids.append(input_ids)
start_token = torch.tensor([[ 128259]], dtype=torch.int64) # Start of human
end_tokens = torch.tensor([[128009, 128260]], dtype=torch.int64) # End of text, End of human
all_modified_input_ids = []
for input_ids in all_input_ids:
modified_input_ids = torch.cat([start_token, input_ids, end_tokens], dim=1) # SOH SOT Text EOT EOH
all_modified_input_ids.append(modified_input_ids)
all_padded_tensors = []
all_attention_masks = []
max_length = max([modified_input_ids.shape[1] for modified_input_ids in all_modified_input_ids])
for modified_input_ids in all_modified_input_ids:
padding = max_length - modified_input_ids.shape[1]
padded_tensor = torch.cat([torch.full((1, padding), 128263, dtype=torch.int64), modified_input_ids], dim=1)
attention_mask = torch.cat([torch.zeros((1, padding), dtype=torch.int64), torch.ones((1, modified_input_ids.shape[1]), dtype=torch.int64)], dim=1)
all_padded_tensors.append(padded_tensor)
all_attention_masks.append(attention_mask)
all_padded_tensors = torch.cat(all_padded_tensors, dim=0)
all_attention_masks = torch.cat(all_attention_masks, dim=0)
input_ids = all_padded_tensors.to("cuda")
attention_mask = all_attention_masks.to("cuda")
generated_ids = model.generate(
input_ids=input_ids,
attention_mask=attention_mask,
max_new_tokens=1200,
do_sample=True,
temperature=0.6,
top_p=0.95,
repetition_penalty=1.1,
num_return_sequences=1,
eos_token_id=128258,
use_cache = True
)
token_to_find = 128257
token_to_remove = 128258
token_indices = (generated_ids == token_to_find).nonzero(as_tuple=True)
if len(token_indices[1]) > 0:
last_occurrence_idx = token_indices[1][-1].item()
cropped_tensor = generated_ids[:, last_occurrence_idx+1:]
else:
cropped_tensor = generated_ids
mask = cropped_tensor != token_to_remove
processed_rows = []
for row in cropped_tensor:
masked_row = row[row != token_to_remove]
processed_rows.append(masked_row)
code_lists = []
for row in processed_rows:
row_length = row.size(0)
new_length = (row_length // 7) * 7
trimmed_row = row[:new_length]
trimmed_row = [t - 128266 for t in trimmed_row]
code_lists.append(trimmed_row)
def redistribute_codes(code_list):
layer_1 = []
layer_2 = []
layer_3 = []
for i in range((len(code_list)+1)//7):
layer_1.append(code_list[7*i])
layer_2.append(code_list[7*i+1]-4096)
layer_3.append(code_list[7*i+2]-(2*4096))
layer_3.append(code_list[7*i+3]-(3*4096))
layer_2.append(code_list[7*i+4]-(4*4096))
layer_3.append(code_list[7*i+5]-(5*4096))
layer_3.append(code_list[7*i+6]-(6*4096))
codes = [torch.tensor(layer_1).unsqueeze(0),
torch.tensor(layer_2).unsqueeze(0),
torch.tensor(layer_3).unsqueeze(0)]
# codes = [c.to("cuda") for c in codes]
audio_hat = snac_model.decode(codes)
return audio_hat
my_samples = []
for code_list in code_lists:
samples = redistribute_codes(code_list)
my_samples.append(samples)
from IPython.display import display, Audio
if len(prompts) != len(my_samples):
raise Exception("Number of prompts and samples do not match")
else:
for i in range(len(my_samples)):
print(prompts[i])
samples = my_samples[i]
display(Audio(samples.detach().squeeze().to("cpu").numpy(), rate=24000))
# Clean up to save RAM
del my_samples,samples
標準推論
必要なパッケージをダウンロードします。
%%capture
!pip install snac ipywebrtc
モデル(SNACとHypa_Orpheus)をダウンロードします。
import torch
from transformers import AutoModelForCausalLM, Trainer, TrainingArguments, AutoTokenizer
from snac import SNAC
# Loads the pre-trained SNAC model and moves it to the CPU.
snac_model = SNAC.from_pretrained("hubertsiuzdak/snac_24khz")
snac_model = snac_model #.to("cpu")
print("We have loaded the Encoder/Decoder model to the cpu, to use vram - use the gpu for faster inference")
# Loading the Orpheus Model and Tokenizer, moving the model to the GPU for faster inference
model_name = "hypaai/Hypa_Orpheus-3b-0.1-ft-unsloth-merged_16bit"
model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype=torch.bfloat16)
model.cuda()
tokenizer = AutoTokenizer.from_pretrained(model_name)
プロンプトを作成し、必要に応じて音声と感情を選択します。
# List of supported voices in Orpheus-TTS
voices = [
"Eniola", "tara", # Female, conversational, clear
"Moyo", "leah", # Female, warm, gentle
"Gift", "jess", # Female, energetic, youthful
"Prince", "leo", # Male, authoritative, deep
"Emmanuel", "dan", # Male, friendly, casual
"Cynthia", "mia", # Female, professional, articulate
"Kolade", "zac", # Male, enthusiastic, dynamic
"Lovelyn", "zoe" # Female, calm, soothing
]
# List of supported emotion tags in Orpheus-TTS
emotions = [
"<laugh>", # Laughter
"<chuckle>", # Soft chuckle
"<sigh>", # Sighing
"<cough>", # Coughing
"<sniffle>", # Sniffling
"<groan>", # Groaning
"<yawn>", # Yawning
"<gasp>" # Gasping
]
# Creating Prompts
prompts = [
"Hey there my name is Eniola 9000, and I'm a speech generation model that can sound like a person.",
# "I've also been taught to understand and produce paralinguistic things like sighing, or chuckling, or yawning!",
# "I live in San Francisco, and have, uhm let's see, 3 billion 7 hundred ... well, lets just say a lot of parameters.",
]
chosen_voice = "Eniola" # "tara" # see github for other voices
prompts = [f"{chosen_voice}: " + p for p in prompts] # Creating the prompts (as a batch)
print(prompts)
プロンプトをトークン化して入力IDに変換し、パディングしてアテンションマスクを作成します。
# Tokenizing each prompt in the
高度な使用法
このモデルの高度な使用法については、上記の基本的な使用法を参考に、必要に応じてパラメータやコードを調整することができます。例えば、異なる音声や感情を選択したり、推論時のパラメータを変更したりすることが可能です。具体的な調整方法は、モデルの特性やタスクに応じて適宜行ってください。
📄 ライセンス
このモデルは Apache-2.0ライセンス の下で提供されています。詳細については、ライセンスファイルを参照してください。




