Commit ·
c69a5b6
1
Parent(s): 6e12827
add
Browse files- .gitignore +1 -0
- __init__.py +14 -14
- config.json +6 -6
- configuration_nanotts.py → configuration_moss_tts_nano.py +5 -2
- gpt2_decoder.py +11 -11
- modeling_nanotts_global_local.py → modeling_moss_tts_nano.py +21 -21
- prompting.py +6 -6
- tokenization_nanotts_sentencepiece.py → tokenization_moss_tts_nano.py +4 -1
- tokenizer_config.json +2 -2
.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
__pycache__
|
__init__.py
CHANGED
|
@@ -1,31 +1,31 @@
|
|
| 1 |
-
from .
|
| 2 |
-
from .
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
)
|
| 7 |
-
from .
|
| 8 |
|
| 9 |
try:
|
| 10 |
-
|
| 11 |
except Exception:
|
| 12 |
pass
|
| 13 |
|
| 14 |
for auto_class_name in ("AutoModel", "AutoModelForCausalLM"):
|
| 15 |
try:
|
| 16 |
-
|
| 17 |
except Exception:
|
| 18 |
pass
|
| 19 |
|
| 20 |
try:
|
| 21 |
-
|
| 22 |
except Exception:
|
| 23 |
pass
|
| 24 |
|
| 25 |
__all__ = [
|
| 26 |
-
"
|
| 27 |
-
"
|
| 28 |
-
"
|
| 29 |
-
"
|
| 30 |
-
"
|
| 31 |
]
|
|
|
|
| 1 |
+
from .configuration_moss_tts_nano import MossTTSNanoConfig
|
| 2 |
+
from .modeling_moss_tts_nano import (
|
| 3 |
+
MossTTSNanoForCausalLM,
|
| 4 |
+
MossTTSNanoGenerationOutput,
|
| 5 |
+
MossTTSNanoOutput,
|
| 6 |
)
|
| 7 |
+
from .tokenization_moss_tts_nano import MossTTSNanoSentencePieceTokenizer
|
| 8 |
|
| 9 |
try:
|
| 10 |
+
MossTTSNanoConfig.register_for_auto_class()
|
| 11 |
except Exception:
|
| 12 |
pass
|
| 13 |
|
| 14 |
for auto_class_name in ("AutoModel", "AutoModelForCausalLM"):
|
| 15 |
try:
|
| 16 |
+
MossTTSNanoForCausalLM.register_for_auto_class(auto_class_name)
|
| 17 |
except Exception:
|
| 18 |
pass
|
| 19 |
|
| 20 |
try:
|
| 21 |
+
MossTTSNanoSentencePieceTokenizer.register_for_auto_class("AutoTokenizer")
|
| 22 |
except Exception:
|
| 23 |
pass
|
| 24 |
|
| 25 |
__all__ = [
|
| 26 |
+
"MossTTSNanoConfig",
|
| 27 |
+
"MossTTSNanoForCausalLM",
|
| 28 |
+
"MossTTSNanoSentencePieceTokenizer",
|
| 29 |
+
"MossTTSNanoGenerationOutput",
|
| 30 |
+
"MossTTSNanoOutput",
|
| 31 |
]
|
config.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
{
|
| 2 |
"add_cross_attention": false,
|
| 3 |
"architectures": [
|
| 4 |
-
"
|
| 5 |
],
|
| 6 |
"attn_implementation": "flash_attention_2",
|
| 7 |
"audio_assistant_slot_token_id": 9,
|
|
@@ -156,7 +156,7 @@
|
|
| 156 |
"max_position_embeddings": 32768,
|
| 157 |
"min_length": 0,
|
| 158 |
"model_architecture": "global_local_transformer",
|
| 159 |
-
"model_type": "
|
| 160 |
"n_vq": 16,
|
| 161 |
"no_repeat_ngram_size": 0,
|
| 162 |
"num_beam_groups": 1,
|
|
@@ -180,7 +180,7 @@
|
|
| 180 |
"tf_legacy_loss": false,
|
| 181 |
"tie_encoder_decoder": false,
|
| 182 |
"tie_word_embeddings": true,
|
| 183 |
-
"tokenizer_class": "
|
| 184 |
"tokenizer_use_fast": false,
|
| 185 |
"top_k": 50,
|
| 186 |
"top_p": 1.0,
|
|
@@ -190,8 +190,8 @@
|
|
| 190 |
"use_bfloat16": false,
|
| 191 |
"vocab_size": 16384,
|
| 192 |
"auto_map": {
|
| 193 |
-
"AutoConfig": "
|
| 194 |
-
"AutoModel": "
|
| 195 |
-
"AutoModelForCausalLM": "
|
| 196 |
}
|
| 197 |
}
|
|
|
|
| 1 |
{
|
| 2 |
"add_cross_attention": false,
|
| 3 |
"architectures": [
|
| 4 |
+
"MossTTSNanoForCausalLM"
|
| 5 |
],
|
| 6 |
"attn_implementation": "flash_attention_2",
|
| 7 |
"audio_assistant_slot_token_id": 9,
|
|
|
|
| 156 |
"max_position_embeddings": 32768,
|
| 157 |
"min_length": 0,
|
| 158 |
"model_architecture": "global_local_transformer",
|
| 159 |
+
"model_type": "moss_tts_nano",
|
| 160 |
"n_vq": 16,
|
| 161 |
"no_repeat_ngram_size": 0,
|
| 162 |
"num_beam_groups": 1,
|
|
|
|
| 180 |
"tf_legacy_loss": false,
|
| 181 |
"tie_encoder_decoder": false,
|
| 182 |
"tie_word_embeddings": true,
|
| 183 |
+
"tokenizer_class": "MossTTSNanoSentencePieceTokenizer",
|
| 184 |
"tokenizer_use_fast": false,
|
| 185 |
"top_k": 50,
|
| 186 |
"top_p": 1.0,
|
|
|
|
| 190 |
"use_bfloat16": false,
|
| 191 |
"vocab_size": 16384,
|
| 192 |
"auto_map": {
|
| 193 |
+
"AutoConfig": "configuration_moss_tts_nano.MossTTSNanoConfig",
|
| 194 |
+
"AutoModel": "modeling_moss_tts_nano.MossTTSNanoForCausalLM",
|
| 195 |
+
"AutoModelForCausalLM": "modeling_moss_tts_nano.MossTTSNanoForCausalLM"
|
| 196 |
}
|
| 197 |
}
|
configuration_nanotts.py → configuration_moss_tts_nano.py
RENAMED
|
@@ -5,8 +5,8 @@ from transformers.configuration_utils import PretrainedConfig
|
|
| 5 |
from transformers.models.gpt2.configuration_gpt2 import GPT2Config
|
| 6 |
|
| 7 |
|
| 8 |
-
class
|
| 9 |
-
model_type = "
|
| 10 |
keys_to_ignore_at_inference = ["past_key_values"]
|
| 11 |
|
| 12 |
def __init__(
|
|
@@ -103,3 +103,6 @@ class NanoTTSConfig(PretrainedConfig):
|
|
| 103 |
output = super().to_dict()
|
| 104 |
output["gpt2_config"] = self.gpt2_config.to_dict()
|
| 105 |
return output
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
from transformers.models.gpt2.configuration_gpt2 import GPT2Config
|
| 6 |
|
| 7 |
|
| 8 |
+
class MossTTSNanoConfig(PretrainedConfig):
|
| 9 |
+
model_type = "moss_tts_nano"
|
| 10 |
keys_to_ignore_at_inference = ["past_key_values"]
|
| 11 |
|
| 12 |
def __init__(
|
|
|
|
| 103 |
output = super().to_dict()
|
| 104 |
output["gpt2_config"] = self.gpt2_config.to_dict()
|
| 105 |
return output
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
__all__ = ["MossTTSNanoConfig"]
|
gpt2_decoder.py
CHANGED
|
@@ -33,7 +33,7 @@ class PackedSequenceMetadata:
|
|
| 33 |
seq_len: Optional[int] = None
|
| 34 |
|
| 35 |
|
| 36 |
-
class
|
| 37 |
def __init__(self, dim: int, base: float = 10000.0) -> None:
|
| 38 |
super().__init__()
|
| 39 |
if dim % 2 != 0:
|
|
@@ -70,7 +70,7 @@ def apply_rotary_pos_emb(
|
|
| 70 |
return (hidden_states * cos) + (rotate_half(hidden_states) * sin)
|
| 71 |
|
| 72 |
|
| 73 |
-
class
|
| 74 |
def __init__(self, config: GPT2Config) -> None:
|
| 75 |
super().__init__()
|
| 76 |
hidden_size = int(config.hidden_size)
|
|
@@ -87,7 +87,7 @@ class NanoGPT2MLP(nn.Module):
|
|
| 87 |
return self.dropout(hidden_states)
|
| 88 |
|
| 89 |
|
| 90 |
-
class
|
| 91 |
def __init__(self, config: GPT2Config, layer_idx: int, attn_implementation: str) -> None:
|
| 92 |
super().__init__()
|
| 93 |
hidden_size = int(config.hidden_size)
|
|
@@ -112,7 +112,7 @@ class NanoGPT2Attention(nn.Module):
|
|
| 112 |
self.c_proj = nn.Linear(hidden_size, hidden_size)
|
| 113 |
self.rotary_emb = None
|
| 114 |
if self.position_embedding_type == "rope":
|
| 115 |
-
self.rotary_emb =
|
| 116 |
self.head_dim,
|
| 117 |
base=float(getattr(config, "rope_base", 10000.0)),
|
| 118 |
)
|
|
@@ -353,14 +353,14 @@ class NanoGPT2Attention(nn.Module):
|
|
| 353 |
return self.resid_dropout(attn_output), present
|
| 354 |
|
| 355 |
|
| 356 |
-
class
|
| 357 |
def __init__(self, config: GPT2Config, layer_idx: int, attn_implementation: str) -> None:
|
| 358 |
super().__init__()
|
| 359 |
hidden_size = int(config.hidden_size)
|
| 360 |
self.ln_1 = nn.LayerNorm(hidden_size, eps=config.layer_norm_epsilon)
|
| 361 |
-
self.attn =
|
| 362 |
self.ln_2 = nn.LayerNorm(hidden_size, eps=config.layer_norm_epsilon)
|
| 363 |
-
self.mlp =
|
| 364 |
|
| 365 |
def forward(
|
| 366 |
self,
|
|
@@ -384,7 +384,7 @@ class NanoGPT2Block(nn.Module):
|
|
| 384 |
return hidden_states, present
|
| 385 |
|
| 386 |
|
| 387 |
-
class
|
| 388 |
def __init__(self, config: GPT2Config, attn_implementation: str = "eager") -> None:
|
| 389 |
super().__init__()
|
| 390 |
self.config = config
|
|
@@ -397,7 +397,7 @@ class NanoGPT2Model(nn.Module):
|
|
| 397 |
self.wpe = nn.Embedding(config.n_positions, hidden_size) if self.position_embedding_type == "absolute" else nn.Identity()
|
| 398 |
self.drop = nn.Dropout(config.embd_pdrop)
|
| 399 |
self.h = nn.ModuleList(
|
| 400 |
-
[
|
| 401 |
)
|
| 402 |
self.ln_f = nn.LayerNorm(hidden_size, eps=config.layer_norm_epsilon)
|
| 403 |
self.gradient_checkpointing = False
|
|
@@ -445,7 +445,7 @@ class NanoGPT2Model(nn.Module):
|
|
| 445 |
batch_size, seq_len = cu_seqlens.shape[0], cu_seqlens.shape[1] - 1
|
| 446 |
device = cu_seqlens.device
|
| 447 |
position_ids = torch.zeros((batch_size, seq_len), dtype=torch.long, device=device)
|
| 448 |
-
counts =
|
| 449 |
for batch_index in range(batch_size):
|
| 450 |
sequence_count = int(counts[batch_index].item())
|
| 451 |
boundaries = cu_seqlens[batch_index, : sequence_count + 1].tolist()
|
|
@@ -467,7 +467,7 @@ class NanoGPT2Model(nn.Module):
|
|
| 467 |
if cu_seqlens.ndim == 1:
|
| 468 |
cu_seqlens = cu_seqlens.unsqueeze(0)
|
| 469 |
device = hidden_states.device
|
| 470 |
-
counts =
|
| 471 |
flat_indices = []
|
| 472 |
cumulative = [0]
|
| 473 |
max_seqlen = 0
|
|
|
|
| 33 |
seq_len: Optional[int] = None
|
| 34 |
|
| 35 |
|
| 36 |
+
class MossTTSNanoGPT2RotaryEmbedding(nn.Module):
|
| 37 |
def __init__(self, dim: int, base: float = 10000.0) -> None:
|
| 38 |
super().__init__()
|
| 39 |
if dim % 2 != 0:
|
|
|
|
| 70 |
return (hidden_states * cos) + (rotate_half(hidden_states) * sin)
|
| 71 |
|
| 72 |
|
| 73 |
+
class MossTTSNanoGPT2MLP(nn.Module):
|
| 74 |
def __init__(self, config: GPT2Config) -> None:
|
| 75 |
super().__init__()
|
| 76 |
hidden_size = int(config.hidden_size)
|
|
|
|
| 87 |
return self.dropout(hidden_states)
|
| 88 |
|
| 89 |
|
| 90 |
+
class MossTTSNanoGPT2Attention(nn.Module):
|
| 91 |
def __init__(self, config: GPT2Config, layer_idx: int, attn_implementation: str) -> None:
|
| 92 |
super().__init__()
|
| 93 |
hidden_size = int(config.hidden_size)
|
|
|
|
| 112 |
self.c_proj = nn.Linear(hidden_size, hidden_size)
|
| 113 |
self.rotary_emb = None
|
| 114 |
if self.position_embedding_type == "rope":
|
| 115 |
+
self.rotary_emb = MossTTSNanoGPT2RotaryEmbedding(
|
| 116 |
self.head_dim,
|
| 117 |
base=float(getattr(config, "rope_base", 10000.0)),
|
| 118 |
)
|
|
|
|
| 353 |
return self.resid_dropout(attn_output), present
|
| 354 |
|
| 355 |
|
| 356 |
+
class MossTTSNanoGPT2Block(nn.Module):
|
| 357 |
def __init__(self, config: GPT2Config, layer_idx: int, attn_implementation: str) -> None:
|
| 358 |
super().__init__()
|
| 359 |
hidden_size = int(config.hidden_size)
|
| 360 |
self.ln_1 = nn.LayerNorm(hidden_size, eps=config.layer_norm_epsilon)
|
| 361 |
+
self.attn = MossTTSNanoGPT2Attention(config, layer_idx=layer_idx, attn_implementation=attn_implementation)
|
| 362 |
self.ln_2 = nn.LayerNorm(hidden_size, eps=config.layer_norm_epsilon)
|
| 363 |
+
self.mlp = MossTTSNanoGPT2MLP(config)
|
| 364 |
|
| 365 |
def forward(
|
| 366 |
self,
|
|
|
|
| 384 |
return hidden_states, present
|
| 385 |
|
| 386 |
|
| 387 |
+
class MossTTSNanoGPT2Model(nn.Module):
|
| 388 |
def __init__(self, config: GPT2Config, attn_implementation: str = "eager") -> None:
|
| 389 |
super().__init__()
|
| 390 |
self.config = config
|
|
|
|
| 397 |
self.wpe = nn.Embedding(config.n_positions, hidden_size) if self.position_embedding_type == "absolute" else nn.Identity()
|
| 398 |
self.drop = nn.Dropout(config.embd_pdrop)
|
| 399 |
self.h = nn.ModuleList(
|
| 400 |
+
[MossTTSNanoGPT2Block(config, layer_idx=index, attn_implementation=attn_implementation) for index in range(config.n_layer)]
|
| 401 |
)
|
| 402 |
self.ln_f = nn.LayerNorm(hidden_size, eps=config.layer_norm_epsilon)
|
| 403 |
self.gradient_checkpointing = False
|
|
|
|
| 445 |
batch_size, seq_len = cu_seqlens.shape[0], cu_seqlens.shape[1] - 1
|
| 446 |
device = cu_seqlens.device
|
| 447 |
position_ids = torch.zeros((batch_size, seq_len), dtype=torch.long, device=device)
|
| 448 |
+
counts = MossTTSNanoGPT2Model._normalize_num_sequences(cu_seqlens, num_sequences, device=device)
|
| 449 |
for batch_index in range(batch_size):
|
| 450 |
sequence_count = int(counts[batch_index].item())
|
| 451 |
boundaries = cu_seqlens[batch_index, : sequence_count + 1].tolist()
|
|
|
|
| 467 |
if cu_seqlens.ndim == 1:
|
| 468 |
cu_seqlens = cu_seqlens.unsqueeze(0)
|
| 469 |
device = hidden_states.device
|
| 470 |
+
counts = MossTTSNanoGPT2Model._normalize_num_sequences(cu_seqlens, num_sequences, device=device)
|
| 471 |
flat_indices = []
|
| 472 |
cumulative = [0]
|
| 473 |
max_seqlen = 0
|
modeling_nanotts_global_local.py → modeling_moss_tts_nano.py
RENAMED
|
@@ -19,19 +19,19 @@ from transformers.modeling_outputs import ModelOutput
|
|
| 19 |
from transformers.modeling_utils import PreTrainedModel
|
| 20 |
from transformers.models.gpt2.configuration_gpt2 import GPT2Config
|
| 21 |
|
| 22 |
-
from .
|
| 23 |
-
from .gpt2_decoder import
|
| 24 |
from .prompting import (
|
| 25 |
build_assistant_prompt_prefix,
|
| 26 |
build_prompt_token_ids,
|
| 27 |
build_user_prompt_after_reference,
|
| 28 |
build_user_prompt_prefix,
|
| 29 |
)
|
| 30 |
-
from .
|
| 31 |
|
| 32 |
|
| 33 |
@dataclass
|
| 34 |
-
class
|
| 35 |
global_hidden_states: Optional[torch.FloatTensor] = None
|
| 36 |
past_key_values: Optional[tuple[tuple[torch.Tensor, torch.Tensor], ...]] = None
|
| 37 |
hidden_states: Optional[tuple[torch.FloatTensor, ...]] = None
|
|
@@ -39,7 +39,7 @@ class NanoTTSOutput(ModelOutput):
|
|
| 39 |
|
| 40 |
|
| 41 |
@dataclass
|
| 42 |
-
class
|
| 43 |
audio_token_ids: torch.LongTensor
|
| 44 |
prompt_input_ids: Optional[torch.LongTensor] = None
|
| 45 |
|
|
@@ -55,24 +55,24 @@ _CLAUSE_SPLIT_PUNCTUATION = frozenset(",,、;;::")
|
|
| 55 |
_CLOSING_PUNCTUATION = frozenset("\"'”’)]})】》」』")
|
| 56 |
|
| 57 |
|
| 58 |
-
class
|
| 59 |
-
config_class =
|
| 60 |
base_model_prefix = "transformer"
|
| 61 |
supports_gradient_checkpointing = False
|
| 62 |
-
_no_split_modules = ["
|
| 63 |
_supports_flash_attn_2 = True
|
| 64 |
_supports_sdpa = True
|
| 65 |
|
| 66 |
|
| 67 |
-
class
|
| 68 |
_keys_to_ignore_on_load_unexpected = [r"local_transformer\.wte\.weight"]
|
| 69 |
|
| 70 |
-
def __init__(self, config:
|
| 71 |
super().__init__(config)
|
| 72 |
config.gpt2_config.pad_token_id = config.pad_token_id
|
| 73 |
config.gpt2_config._attn_implementation = config.attn_implementation
|
| 74 |
|
| 75 |
-
self.transformer =
|
| 76 |
config.gpt2_config,
|
| 77 |
attn_implementation=config.attn_implementation,
|
| 78 |
)
|
|
@@ -97,7 +97,7 @@ class NanoTTSGlobalLocalForCausalLM(NanoTTSPreTrainedModel):
|
|
| 97 |
local_gpt2_config["n_layer"] = int(config.local_transformer_layers)
|
| 98 |
local_gpt2_config["n_positions"] = config.n_vq + 1
|
| 99 |
local_gpt2_config["n_ctx"] = config.n_vq + 1
|
| 100 |
-
self.local_transformer =
|
| 101 |
GPT2Config(**local_gpt2_config),
|
| 102 |
attn_implementation=str(config.local_transformer_attn_implementation),
|
| 103 |
)
|
|
@@ -210,7 +210,7 @@ class NanoTTSGlobalLocalForCausalLM(NanoTTSPreTrainedModel):
|
|
| 210 |
outputs.attentions,
|
| 211 |
)
|
| 212 |
|
| 213 |
-
return
|
| 214 |
global_hidden_states=outputs.last_hidden_state,
|
| 215 |
past_key_values=outputs.past_key_values,
|
| 216 |
hidden_states=outputs.hidden_states,
|
|
@@ -258,7 +258,7 @@ class NanoTTSGlobalLocalForCausalLM(NanoTTSPreTrainedModel):
|
|
| 258 |
while " " in normalized_text:
|
| 259 |
normalized_text = normalized_text.replace(" ", " ")
|
| 260 |
|
| 261 |
-
contains_cjk =
|
| 262 |
if contains_cjk:
|
| 263 |
if normalized_text[-1] not in _SENTENCE_END_PUNCTUATION:
|
| 264 |
normalized_text = normalized_text + "。"
|
|
@@ -360,7 +360,7 @@ class NanoTTSGlobalLocalForCausalLM(NanoTTSPreTrainedModel):
|
|
| 360 |
return right
|
| 361 |
if not right:
|
| 362 |
return left
|
| 363 |
-
if
|
| 364 |
return left + right
|
| 365 |
return left + " " + right
|
| 366 |
|
|
@@ -880,7 +880,7 @@ class NanoTTSGlobalLocalForCausalLM(NanoTTSPreTrainedModel):
|
|
| 880 |
sample_rate: int,
|
| 881 |
first_audio_emitted_at: Optional[float],
|
| 882 |
) -> int:
|
| 883 |
-
lead_seconds =
|
| 884 |
emitted_samples_total=emitted_samples_total,
|
| 885 |
sample_rate=sample_rate,
|
| 886 |
first_audio_emitted_at=first_audio_emitted_at,
|
|
@@ -1040,7 +1040,7 @@ class NanoTTSGlobalLocalForCausalLM(NanoTTSPreTrainedModel):
|
|
| 1040 |
hf_dir = candidate_path / "hf_tokenizer"
|
| 1041 |
if self._looks_like_hf_tokenizer_dir(hf_dir):
|
| 1042 |
return hf_dir
|
| 1043 |
-
sentencepiece_model = candidate_path / "sentencepiece" / "
|
| 1044 |
if sentencepiece_model.is_file():
|
| 1045 |
return sentencepiece_model
|
| 1046 |
final_summary_path = candidate_path / "final_summary.json"
|
|
@@ -1057,7 +1057,7 @@ class NanoTTSGlobalLocalForCausalLM(NanoTTSPreTrainedModel):
|
|
| 1057 |
|
| 1058 |
def _load_resolved_text_tokenizer(self, resolved_path: Path, cache_dir: str):
|
| 1059 |
if resolved_path.is_file() and resolved_path.suffix == ".model":
|
| 1060 |
-
return
|
| 1061 |
try:
|
| 1062 |
return AutoTokenizer.from_pretrained(
|
| 1063 |
str(resolved_path),
|
|
@@ -1069,7 +1069,7 @@ class NanoTTSGlobalLocalForCausalLM(NanoTTSPreTrainedModel):
|
|
| 1069 |
except Exception:
|
| 1070 |
model_path = resolved_path / "tokenizer.model"
|
| 1071 |
if model_path.is_file():
|
| 1072 |
-
return
|
| 1073 |
raise
|
| 1074 |
|
| 1075 |
@staticmethod
|
|
@@ -1276,7 +1276,7 @@ class NanoTTSGlobalLocalForCausalLM(NanoTTSPreTrainedModel):
|
|
| 1276 |
if isinstance(output, (list, tuple)) and output:
|
| 1277 |
if len(output) == 2 and isinstance(output[1], (int, float)):
|
| 1278 |
return output[0]
|
| 1279 |
-
return
|
| 1280 |
raise TypeError(f"Unsupported audio tokenizer output type: {type(output)!r}")
|
| 1281 |
|
| 1282 |
@staticmethod
|
|
@@ -1750,7 +1750,7 @@ class NanoTTSGlobalLocalForCausalLM(NanoTTSPreTrainedModel):
|
|
| 1750 |
return
|
| 1751 |
yield {
|
| 1752 |
"type": "final",
|
| 1753 |
-
"generation":
|
| 1754 |
}
|
| 1755 |
|
| 1756 |
@torch.no_grad()
|
|
|
|
| 19 |
from transformers.modeling_utils import PreTrainedModel
|
| 20 |
from transformers.models.gpt2.configuration_gpt2 import GPT2Config
|
| 21 |
|
| 22 |
+
from .configuration_moss_tts_nano import MossTTSNanoConfig
|
| 23 |
+
from .gpt2_decoder import MossTTSNanoGPT2Block, MossTTSNanoGPT2Model
|
| 24 |
from .prompting import (
|
| 25 |
build_assistant_prompt_prefix,
|
| 26 |
build_prompt_token_ids,
|
| 27 |
build_user_prompt_after_reference,
|
| 28 |
build_user_prompt_prefix,
|
| 29 |
)
|
| 30 |
+
from .tokenization_moss_tts_nano import MossTTSNanoSentencePieceTokenizer
|
| 31 |
|
| 32 |
|
| 33 |
@dataclass
|
| 34 |
+
class MossTTSNanoOutput(ModelOutput):
|
| 35 |
global_hidden_states: Optional[torch.FloatTensor] = None
|
| 36 |
past_key_values: Optional[tuple[tuple[torch.Tensor, torch.Tensor], ...]] = None
|
| 37 |
hidden_states: Optional[tuple[torch.FloatTensor, ...]] = None
|
|
|
|
| 39 |
|
| 40 |
|
| 41 |
@dataclass
|
| 42 |
+
class MossTTSNanoGenerationOutput(ModelOutput):
|
| 43 |
audio_token_ids: torch.LongTensor
|
| 44 |
prompt_input_ids: Optional[torch.LongTensor] = None
|
| 45 |
|
|
|
|
| 55 |
_CLOSING_PUNCTUATION = frozenset("\"'”’)]})】》」』")
|
| 56 |
|
| 57 |
|
| 58 |
+
class MossTTSNanoPreTrainedModel(PreTrainedModel):
|
| 59 |
+
config_class = MossTTSNanoConfig
|
| 60 |
base_model_prefix = "transformer"
|
| 61 |
supports_gradient_checkpointing = False
|
| 62 |
+
_no_split_modules = ["MossTTSNanoGPT2Block"]
|
| 63 |
_supports_flash_attn_2 = True
|
| 64 |
_supports_sdpa = True
|
| 65 |
|
| 66 |
|
| 67 |
+
class MossTTSNanoForCausalLM(MossTTSNanoPreTrainedModel):
|
| 68 |
_keys_to_ignore_on_load_unexpected = [r"local_transformer\.wte\.weight"]
|
| 69 |
|
| 70 |
+
def __init__(self, config: MossTTSNanoConfig) -> None:
|
| 71 |
super().__init__(config)
|
| 72 |
config.gpt2_config.pad_token_id = config.pad_token_id
|
| 73 |
config.gpt2_config._attn_implementation = config.attn_implementation
|
| 74 |
|
| 75 |
+
self.transformer = MossTTSNanoGPT2Model(
|
| 76 |
config.gpt2_config,
|
| 77 |
attn_implementation=config.attn_implementation,
|
| 78 |
)
|
|
|
|
| 97 |
local_gpt2_config["n_layer"] = int(config.local_transformer_layers)
|
| 98 |
local_gpt2_config["n_positions"] = config.n_vq + 1
|
| 99 |
local_gpt2_config["n_ctx"] = config.n_vq + 1
|
| 100 |
+
self.local_transformer = MossTTSNanoGPT2Model(
|
| 101 |
GPT2Config(**local_gpt2_config),
|
| 102 |
attn_implementation=str(config.local_transformer_attn_implementation),
|
| 103 |
)
|
|
|
|
| 210 |
outputs.attentions,
|
| 211 |
)
|
| 212 |
|
| 213 |
+
return MossTTSNanoOutput(
|
| 214 |
global_hidden_states=outputs.last_hidden_state,
|
| 215 |
past_key_values=outputs.past_key_values,
|
| 216 |
hidden_states=outputs.hidden_states,
|
|
|
|
| 258 |
while " " in normalized_text:
|
| 259 |
normalized_text = normalized_text.replace(" ", " ")
|
| 260 |
|
| 261 |
+
contains_cjk = MossTTSNanoForCausalLM._contains_cjk(normalized_text)
|
| 262 |
if contains_cjk:
|
| 263 |
if normalized_text[-1] not in _SENTENCE_END_PUNCTUATION:
|
| 264 |
normalized_text = normalized_text + "。"
|
|
|
|
| 360 |
return right
|
| 361 |
if not right:
|
| 362 |
return left
|
| 363 |
+
if MossTTSNanoForCausalLM._contains_cjk(left) or MossTTSNanoForCausalLM._contains_cjk(right):
|
| 364 |
return left + right
|
| 365 |
return left + " " + right
|
| 366 |
|
|
|
|
| 880 |
sample_rate: int,
|
| 881 |
first_audio_emitted_at: Optional[float],
|
| 882 |
) -> int:
|
| 883 |
+
lead_seconds = MossTTSNanoForCausalLM._compute_stream_lead_seconds(
|
| 884 |
emitted_samples_total=emitted_samples_total,
|
| 885 |
sample_rate=sample_rate,
|
| 886 |
first_audio_emitted_at=first_audio_emitted_at,
|
|
|
|
| 1040 |
hf_dir = candidate_path / "hf_tokenizer"
|
| 1041 |
if self._looks_like_hf_tokenizer_dir(hf_dir):
|
| 1042 |
return hf_dir
|
| 1043 |
+
sentencepiece_model = candidate_path / "sentencepiece" / "mossttsnano_spm_bpe.model"
|
| 1044 |
if sentencepiece_model.is_file():
|
| 1045 |
return sentencepiece_model
|
| 1046 |
final_summary_path = candidate_path / "final_summary.json"
|
|
|
|
| 1057 |
|
| 1058 |
def _load_resolved_text_tokenizer(self, resolved_path: Path, cache_dir: str):
|
| 1059 |
if resolved_path.is_file() and resolved_path.suffix == ".model":
|
| 1060 |
+
return MossTTSNanoSentencePieceTokenizer(vocab_file=str(resolved_path))
|
| 1061 |
try:
|
| 1062 |
return AutoTokenizer.from_pretrained(
|
| 1063 |
str(resolved_path),
|
|
|
|
| 1069 |
except Exception:
|
| 1070 |
model_path = resolved_path / "tokenizer.model"
|
| 1071 |
if model_path.is_file():
|
| 1072 |
+
return MossTTSNanoSentencePieceTokenizer(vocab_file=str(model_path))
|
| 1073 |
raise
|
| 1074 |
|
| 1075 |
@staticmethod
|
|
|
|
| 1276 |
if isinstance(output, (list, tuple)) and output:
|
| 1277 |
if len(output) == 2 and isinstance(output[1], (int, float)):
|
| 1278 |
return output[0]
|
| 1279 |
+
return MossTTSNanoForCausalLM._extract_tensor_candidate(output[0])
|
| 1280 |
raise TypeError(f"Unsupported audio tokenizer output type: {type(output)!r}")
|
| 1281 |
|
| 1282 |
@staticmethod
|
|
|
|
| 1750 |
return
|
| 1751 |
yield {
|
| 1752 |
"type": "final",
|
| 1753 |
+
"generation": MossTTSNanoGenerationOutput(audio_token_ids=audio_token_ids, prompt_input_ids=input_ids),
|
| 1754 |
}
|
| 1755 |
|
| 1756 |
@torch.no_grad()
|
prompting.py
CHANGED
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
| 2 |
|
| 3 |
from typing import List, Sequence
|
| 4 |
|
| 5 |
-
from .
|
| 6 |
|
| 7 |
|
| 8 |
USER_ROLE_PREFIX = "user\n"
|
|
@@ -48,7 +48,7 @@ def decode_text(tokenizer, token_ids: Sequence[int]) -> str:
|
|
| 48 |
return str(tokenizer.decode(list(token_ids)))
|
| 49 |
|
| 50 |
|
| 51 |
-
def build_user_prompt_prefix(tokenizer, config:
|
| 52 |
return [config.im_start_token_id] + encode_text(tokenizer, USER_ROLE_PREFIX) + encode_text(
|
| 53 |
tokenizer,
|
| 54 |
USER_TEMPLATE_REFERENCE_PREFIX,
|
|
@@ -59,7 +59,7 @@ def build_user_prompt_after_reference(tokenizer) -> List[int]:
|
|
| 59 |
return encode_text(tokenizer, USER_TEMPLATE_AFTER_REFERENCE)
|
| 60 |
|
| 61 |
|
| 62 |
-
def build_assistant_prompt_prefix(tokenizer, config:
|
| 63 |
return encode_text(tokenizer, USER_TEMPLATE_SUFFIX) + [config.im_end_token_id] + encode_text(
|
| 64 |
tokenizer,
|
| 65 |
ASSISTANT_TURN_PREFIX,
|
|
@@ -69,7 +69,7 @@ def build_assistant_prompt_prefix(tokenizer, config: NanoTTSConfig) -> List[int]
|
|
| 69 |
)
|
| 70 |
|
| 71 |
|
| 72 |
-
def build_prompt_prefix(tokenizer, config:
|
| 73 |
return (
|
| 74 |
build_user_prompt_prefix(tokenizer, config)
|
| 75 |
+ encode_text(tokenizer, "None")
|
|
@@ -77,13 +77,13 @@ def build_prompt_prefix(tokenizer, config: NanoTTSConfig) -> List[int]:
|
|
| 77 |
)
|
| 78 |
|
| 79 |
|
| 80 |
-
def build_prompt_suffix(tokenizer, config:
|
| 81 |
return build_assistant_prompt_prefix(tokenizer, config)
|
| 82 |
|
| 83 |
|
| 84 |
def build_prompt_token_ids(
|
| 85 |
tokenizer,
|
| 86 |
-
config:
|
| 87 |
text_token_ids: Sequence[int],
|
| 88 |
) -> List[int]:
|
| 89 |
return build_prompt_prefix(tokenizer, config) + [int(token_id) for token_id in text_token_ids] + build_prompt_suffix(
|
|
|
|
| 2 |
|
| 3 |
from typing import List, Sequence
|
| 4 |
|
| 5 |
+
from .configuration_moss_tts_nano import MossTTSNanoConfig
|
| 6 |
|
| 7 |
|
| 8 |
USER_ROLE_PREFIX = "user\n"
|
|
|
|
| 48 |
return str(tokenizer.decode(list(token_ids)))
|
| 49 |
|
| 50 |
|
| 51 |
+
def build_user_prompt_prefix(tokenizer, config: MossTTSNanoConfig) -> List[int]:
|
| 52 |
return [config.im_start_token_id] + encode_text(tokenizer, USER_ROLE_PREFIX) + encode_text(
|
| 53 |
tokenizer,
|
| 54 |
USER_TEMPLATE_REFERENCE_PREFIX,
|
|
|
|
| 59 |
return encode_text(tokenizer, USER_TEMPLATE_AFTER_REFERENCE)
|
| 60 |
|
| 61 |
|
| 62 |
+
def build_assistant_prompt_prefix(tokenizer, config: MossTTSNanoConfig) -> List[int]:
|
| 63 |
return encode_text(tokenizer, USER_TEMPLATE_SUFFIX) + [config.im_end_token_id] + encode_text(
|
| 64 |
tokenizer,
|
| 65 |
ASSISTANT_TURN_PREFIX,
|
|
|
|
| 69 |
)
|
| 70 |
|
| 71 |
|
| 72 |
+
def build_prompt_prefix(tokenizer, config: MossTTSNanoConfig) -> List[int]:
|
| 73 |
return (
|
| 74 |
build_user_prompt_prefix(tokenizer, config)
|
| 75 |
+ encode_text(tokenizer, "None")
|
|
|
|
| 77 |
)
|
| 78 |
|
| 79 |
|
| 80 |
+
def build_prompt_suffix(tokenizer, config: MossTTSNanoConfig) -> List[int]:
|
| 81 |
return build_assistant_prompt_prefix(tokenizer, config)
|
| 82 |
|
| 83 |
|
| 84 |
def build_prompt_token_ids(
|
| 85 |
tokenizer,
|
| 86 |
+
config: MossTTSNanoConfig,
|
| 87 |
text_token_ids: Sequence[int],
|
| 88 |
) -> List[int]:
|
| 89 |
return build_prompt_prefix(tokenizer, config) + [int(token_id) for token_id in text_token_ids] + build_prompt_suffix(
|
tokenization_nanotts_sentencepiece.py → tokenization_moss_tts_nano.py
RENAMED
|
@@ -11,7 +11,7 @@ from transformers import PreTrainedTokenizer
|
|
| 11 |
VOCAB_FILES_NAMES = {"vocab_file": "tokenizer.model"}
|
| 12 |
|
| 13 |
|
| 14 |
-
class
|
| 15 |
vocab_files_names = VOCAB_FILES_NAMES
|
| 16 |
model_input_names = ["input_ids", "attention_mask"]
|
| 17 |
|
|
@@ -101,3 +101,6 @@ class NanoTTSSentencePieceTokenizer(PreTrainedTokenizer):
|
|
| 101 |
if token_ids_1 is None:
|
| 102 |
return [0] * len(token_ids_0)
|
| 103 |
return [0] * (len(token_ids_0) + len(token_ids_1))
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
VOCAB_FILES_NAMES = {"vocab_file": "tokenizer.model"}
|
| 12 |
|
| 13 |
|
| 14 |
+
class MossTTSNanoSentencePieceTokenizer(PreTrainedTokenizer):
|
| 15 |
vocab_files_names = VOCAB_FILES_NAMES
|
| 16 |
model_input_names = ["input_ids", "attention_mask"]
|
| 17 |
|
|
|
|
| 101 |
if token_ids_1 is None:
|
| 102 |
return [0] * len(token_ids_0)
|
| 103 |
return [0] * (len(token_ids_0) + len(token_ids_1))
|
| 104 |
+
|
| 105 |
+
|
| 106 |
+
__all__ = ["MossTTSNanoSentencePieceTokenizer"]
|
tokenizer_config.json
CHANGED
|
@@ -36,7 +36,7 @@
|
|
| 36 |
"additional_special_tokens": [],
|
| 37 |
"auto_map": {
|
| 38 |
"AutoTokenizer": [
|
| 39 |
-
"
|
| 40 |
null
|
| 41 |
]
|
| 42 |
},
|
|
@@ -47,6 +47,6 @@
|
|
| 47 |
"extra_special_tokens": {},
|
| 48 |
"model_max_length": 16384,
|
| 49 |
"pad_token": "<pad>",
|
| 50 |
-
"tokenizer_class": "
|
| 51 |
"unk_token": "<unk>"
|
| 52 |
}
|
|
|
|
| 36 |
"additional_special_tokens": [],
|
| 37 |
"auto_map": {
|
| 38 |
"AutoTokenizer": [
|
| 39 |
+
"tokenization_moss_tts_nano.MossTTSNanoSentencePieceTokenizer",
|
| 40 |
null
|
| 41 |
]
|
| 42 |
},
|
|
|
|
| 47 |
"extra_special_tokens": {},
|
| 48 |
"model_max_length": 16384,
|
| 49 |
"pad_token": "<pad>",
|
| 50 |
+
"tokenizer_class": "MossTTSNanoSentencePieceTokenizer",
|
| 51 |
"unk_token": "<unk>"
|
| 52 |
}
|