Feature Extraction
Transformers
Safetensors
moss-audio-tokenizer
audio
audio-tokenizer
neural-codec
moss-tts-family
MOSS Audio Tokenizer
speech-tokenizer
trust-remote-code
custom_code
Instructions to use OpenMOSS-Team/MOSS-Audio-Tokenizer-v2 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use OpenMOSS-Team/MOSS-Audio-Tokenizer-v2 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("feature-extraction", model="OpenMOSS-Team/MOSS-Audio-Tokenizer-v2", trust_remote_code=True)# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("OpenMOSS-Team/MOSS-Audio-Tokenizer-v2", trust_remote_code=True, dtype="auto") - Notebooks
- Google Colab
- Kaggle
KuangWei Chen commited on
Commit ·
fed8398
1
Parent(s): 5c74984
Update MOSS Audio Tokenizer v2 weight dtype loading methods
Browse files- README.md +18 -1
- configuration_moss_audio_tokenizer.py +8 -0
- modeling_moss_audio_tokenizer.py +88 -1
README.md
CHANGED
|
@@ -82,13 +82,30 @@ For production use with `trust_remote_code=True`, pin `revision` to a reviewed c
|
|
| 82 |
|
| 83 |
`config.attention_implementation` controls whether transformer layers prefer `sdpa` or `flash_attention_2`.
|
| 84 |
`config.compute_dtype` controls the non-quantizer autocast dtype and supports `fp32`, `bf16`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 85 |
|
| 86 |
```python
|
| 87 |
model.set_attention_implementation("flash_attention_2")
|
| 88 |
model.set_compute_dtype("bf16")
|
|
|
|
| 89 |
```
|
| 90 |
|
| 91 |
-
|
| 92 |
|
| 93 |
### Streaming
|
| 94 |
|
|
|
|
| 82 |
|
| 83 |
`config.attention_implementation` controls whether transformer layers prefer `sdpa` or `flash_attention_2`.
|
| 84 |
`config.compute_dtype` controls the non-quantizer autocast dtype and supports `fp32`, `bf16`.
|
| 85 |
+
`config.codec_weight_dtype` controls encoder/decoder parameter dtype and defaults to `fp32`.
|
| 86 |
+
The quantizer is always kept in fp32.
|
| 87 |
+
|
| 88 |
+
GPU bf16 loading:
|
| 89 |
+
|
| 90 |
+
```python
|
| 91 |
+
import torch
|
| 92 |
+
from transformers import AutoModel
|
| 93 |
+
|
| 94 |
+
repo_id = "OpenMOSS-Team/MOSS-Audio-Tokenizer-v2"
|
| 95 |
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
| 96 |
+
model = AutoModel.from_pretrained(repo_id, trust_remote_code=True, low_cpu_mem_usage=True, codec_weight_dtype="bf16").eval().to(device)
|
| 97 |
+
```
|
| 98 |
+
Passing codec_weight_dtype="bf16" at load time avoids first materializing encoder/decoder weights as fp32 on GPU and then converting them to bf16, which would increase peak GPU memory.
|
| 99 |
+
|
| 100 |
+
You can also switch an already loaded model:
|
| 101 |
|
| 102 |
```python
|
| 103 |
model.set_attention_implementation("flash_attention_2")
|
| 104 |
model.set_compute_dtype("bf16")
|
| 105 |
+
model.set_codec_weight_dtype("bf16") # encoder/decoder bf16, quantizer fp32
|
| 106 |
```
|
| 107 |
|
| 108 |
+
Avoid calling plain `model.to(torch.bfloat16)` on the whole codec; that also casts quantizer weights and can cause dtype mismatches or serious precision loss.
|
| 109 |
|
| 110 |
### Streaming
|
| 111 |
|
configuration_moss_audio_tokenizer.py
CHANGED
|
@@ -59,6 +59,9 @@ class MossAudioTokenizerConfig(PreTrainedConfig):
|
|
| 59 |
`"flash_attention_2"`.
|
| 60 |
compute_dtype (`str`, *optional*, defaults to `"fp32"`):
|
| 61 |
Inference compute dtype for non-quantizer modules. Supported values are `"fp32"`, `"bf16"`.
|
|
|
|
|
|
|
|
|
|
| 62 |
quantizer_type (`str`, *optional*, defaults to `"rlfq"`):
|
| 63 |
Quantizer type. Options include `"rvq"`, `"spec_rvq"`, `"rlfq"`, `"random_prefix_rlfq"`.
|
| 64 |
quantizer_kwargs (`dict`, *optional*):
|
|
@@ -95,6 +98,7 @@ class MossAudioTokenizerConfig(PreTrainedConfig):
|
|
| 95 |
enable_channel_interleave: bool
|
| 96 |
attention_implementation: str
|
| 97 |
compute_dtype: str
|
|
|
|
| 98 |
quantizer_type: str
|
| 99 |
quantizer_kwargs: dict[str, Any]
|
| 100 |
|
|
@@ -110,6 +114,7 @@ class MossAudioTokenizerConfig(PreTrainedConfig):
|
|
| 110 |
enable_channel_interleave: bool = True,
|
| 111 |
attention_implementation: str = "sdpa",
|
| 112 |
compute_dtype: str = "fp32",
|
|
|
|
| 113 |
quantizer_type: str = "rlfq",
|
| 114 |
quantizer_kwargs: dict[str, Any] | None = None,
|
| 115 |
**kwargs,
|
|
@@ -125,6 +130,8 @@ class MossAudioTokenizerConfig(PreTrainedConfig):
|
|
| 125 |
attention_implementation = kwargs.pop("attention_backend")
|
| 126 |
if "codec_compute_dtype" in kwargs and compute_dtype == "fp32":
|
| 127 |
compute_dtype = kwargs.pop("codec_compute_dtype")
|
|
|
|
|
|
|
| 128 |
reversed_decoder_kwargs = kwargs.pop("reversed_decoder_kwargs", None)
|
| 129 |
|
| 130 |
# `version` is accepted for compatibility but not used in modeling.
|
|
@@ -136,6 +143,7 @@ class MossAudioTokenizerConfig(PreTrainedConfig):
|
|
| 136 |
self.enable_channel_interleave = enable_channel_interleave
|
| 137 |
self.attention_implementation = attention_implementation
|
| 138 |
self.compute_dtype = compute_dtype
|
|
|
|
| 139 |
# Default encoder configuration
|
| 140 |
if encoder_kwargs is None:
|
| 141 |
encoder_kwargs = [
|
|
|
|
| 59 |
`"flash_attention_2"`.
|
| 60 |
compute_dtype (`str`, *optional*, defaults to `"fp32"`):
|
| 61 |
Inference compute dtype for non-quantizer modules. Supported values are `"fp32"`, `"bf16"`.
|
| 62 |
+
codec_weight_dtype (`str`, *optional*, defaults to `"fp32"`):
|
| 63 |
+
Parameter dtype for encoder and decoder modules. The quantizer remains fp32 because it explicitly disables
|
| 64 |
+
autocast and performs numerically sensitive codebook operations in fp32.
|
| 65 |
quantizer_type (`str`, *optional*, defaults to `"rlfq"`):
|
| 66 |
Quantizer type. Options include `"rvq"`, `"spec_rvq"`, `"rlfq"`, `"random_prefix_rlfq"`.
|
| 67 |
quantizer_kwargs (`dict`, *optional*):
|
|
|
|
| 98 |
enable_channel_interleave: bool
|
| 99 |
attention_implementation: str
|
| 100 |
compute_dtype: str
|
| 101 |
+
codec_weight_dtype: str
|
| 102 |
quantizer_type: str
|
| 103 |
quantizer_kwargs: dict[str, Any]
|
| 104 |
|
|
|
|
| 114 |
enable_channel_interleave: bool = True,
|
| 115 |
attention_implementation: str = "sdpa",
|
| 116 |
compute_dtype: str = "fp32",
|
| 117 |
+
codec_weight_dtype: str = "fp32",
|
| 118 |
quantizer_type: str = "rlfq",
|
| 119 |
quantizer_kwargs: dict[str, Any] | None = None,
|
| 120 |
**kwargs,
|
|
|
|
| 130 |
attention_implementation = kwargs.pop("attention_backend")
|
| 131 |
if "codec_compute_dtype" in kwargs and compute_dtype == "fp32":
|
| 132 |
compute_dtype = kwargs.pop("codec_compute_dtype")
|
| 133 |
+
if "codec_load_dtype" in kwargs and codec_weight_dtype == "fp32":
|
| 134 |
+
codec_weight_dtype = kwargs.pop("codec_load_dtype")
|
| 135 |
reversed_decoder_kwargs = kwargs.pop("reversed_decoder_kwargs", None)
|
| 136 |
|
| 137 |
# `version` is accepted for compatibility but not used in modeling.
|
|
|
|
| 143 |
self.enable_channel_interleave = enable_channel_interleave
|
| 144 |
self.attention_implementation = attention_implementation
|
| 145 |
self.compute_dtype = compute_dtype
|
| 146 |
+
self.codec_weight_dtype = codec_weight_dtype
|
| 147 |
# Default encoder configuration
|
| 148 |
if encoder_kwargs is None:
|
| 149 |
encoder_kwargs = [
|
modeling_moss_audio_tokenizer.py
CHANGED
|
@@ -62,6 +62,18 @@ except ImportError:
|
|
| 62 |
|
| 63 |
SUPPORTED_ATTENTION_IMPLEMENTATIONS = {"sdpa", "flash_attention_2"}
|
| 64 |
SUPPORTED_COMPUTE_DTYPES = {"fp32": None, "bf16": torch.bfloat16}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
|
| 66 |
|
| 67 |
def resolve_compute_dtype(compute_dtype: str) -> torch.dtype | None:
|
|
@@ -72,6 +84,26 @@ def resolve_compute_dtype(compute_dtype: str) -> torch.dtype | None:
|
|
| 72 |
return SUPPORTED_COMPUTE_DTYPES[compute_dtype]
|
| 73 |
|
| 74 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
@contextmanager
|
| 76 |
def disable_cuda_autocast():
|
| 77 |
with torch.autocast(device_type="cuda", enabled=False):
|
|
@@ -715,7 +747,7 @@ class MossAudioTokenizerMultiheadAttention(StreamingModule):
|
|
| 715 |
)
|
| 716 |
|
| 717 |
def _supports_flash_attention(self, device: torch.device, dtype: torch.dtype) -> bool:
|
| 718 |
-
return HAS_FLASH_ATTN and device.type == "cuda" and dtype
|
| 719 |
|
| 720 |
def _get_backend_check_dtype(self, x: torch.Tensor) -> torch.dtype:
|
| 721 |
if x.device.type != "cuda":
|
|
@@ -1778,6 +1810,9 @@ class MossAudioTokenizerModel(MossAudioTokenizerPreTrainedModel):
|
|
| 1778 |
self.attention_implementation = config.attention_implementation
|
| 1779 |
self.compute_dtype_name = config.compute_dtype
|
| 1780 |
self.compute_dtype = resolve_compute_dtype(config.compute_dtype)
|
|
|
|
|
|
|
|
|
|
| 1781 |
|
| 1782 |
encoder_context_durations = [
|
| 1783 |
float(module_kwargs.get("context_duration", config.causal_transformer_context_duration))
|
|
@@ -1848,6 +1883,21 @@ class MossAudioTokenizerModel(MossAudioTokenizerPreTrainedModel):
|
|
| 1848 |
|
| 1849 |
self.post_init()
|
| 1850 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1851 |
def _start_streaming(self, batch_size: int):
|
| 1852 |
"""Start streaming mode for all modules."""
|
| 1853 |
|
|
@@ -1936,6 +1986,9 @@ class MossAudioTokenizerModel(MossAudioTokenizerPreTrainedModel):
|
|
| 1936 |
if device.type == "cuda" and self.compute_dtype is not None:
|
| 1937 |
with torch.autocast(device_type="cuda", dtype=self.compute_dtype):
|
| 1938 |
yield
|
|
|
|
|
|
|
|
|
|
| 1939 |
else:
|
| 1940 |
yield
|
| 1941 |
|
|
@@ -1948,6 +2001,37 @@ class MossAudioTokenizerModel(MossAudioTokenizerPreTrainedModel):
|
|
| 1948 |
def set_compute_dtype(self, compute_dtype: str) -> None:
|
| 1949 |
self.compute_dtype_name = compute_dtype
|
| 1950 |
self.compute_dtype = resolve_compute_dtype(compute_dtype)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1951 |
|
| 1952 |
def _prepare_waveform_batch(
|
| 1953 |
self,
|
|
@@ -2117,6 +2201,9 @@ class MossAudioTokenizerModel(MossAudioTokenizerPreTrainedModel):
|
|
| 2117 |
|
| 2118 |
quantizer = cast(MossAudioTokenizerResidualVQ | MossAudioTokenizerResidualLFQ, self.quantizer)
|
| 2119 |
_, audio_codes, audio_codes_lengths = quantizer(encoder_hidden_states.float(), encoder_hidden_lengths, n_quantizers)
|
|
|
|
|
|
|
|
|
|
| 2120 |
|
| 2121 |
return MossAudioTokenizerEncoderOutput(
|
| 2122 |
audio_codes=audio_codes,
|
|
|
|
| 62 |
|
| 63 |
SUPPORTED_ATTENTION_IMPLEMENTATIONS = {"sdpa", "flash_attention_2"}
|
| 64 |
SUPPORTED_COMPUTE_DTYPES = {"fp32": None, "bf16": torch.bfloat16}
|
| 65 |
+
SUPPORTED_CODEC_WEIGHT_DTYPES = {
|
| 66 |
+
"fp32": torch.float32,
|
| 67 |
+
"float32": torch.float32,
|
| 68 |
+
"bf16": torch.bfloat16,
|
| 69 |
+
"bfloat16": torch.bfloat16,
|
| 70 |
+
}
|
| 71 |
+
CANONICAL_CODEC_WEIGHT_DTYPES = {
|
| 72 |
+
"fp32": "fp32",
|
| 73 |
+
"float32": "fp32",
|
| 74 |
+
"bf16": "bf16",
|
| 75 |
+
"bfloat16": "bf16",
|
| 76 |
+
}
|
| 77 |
|
| 78 |
|
| 79 |
def resolve_compute_dtype(compute_dtype: str) -> torch.dtype | None:
|
|
|
|
| 84 |
return SUPPORTED_COMPUTE_DTYPES[compute_dtype]
|
| 85 |
|
| 86 |
|
| 87 |
+
def canonicalize_codec_weight_dtype(codec_weight_dtype: str) -> str:
|
| 88 |
+
key = str(codec_weight_dtype).lower()
|
| 89 |
+
if key not in CANONICAL_CODEC_WEIGHT_DTYPES:
|
| 90 |
+
raise ValueError(
|
| 91 |
+
"Unsupported codec_weight_dtype="
|
| 92 |
+
f"{codec_weight_dtype!r}. Expected one of {sorted(CANONICAL_CODEC_WEIGHT_DTYPES)}."
|
| 93 |
+
)
|
| 94 |
+
return CANONICAL_CODEC_WEIGHT_DTYPES[key]
|
| 95 |
+
|
| 96 |
+
|
| 97 |
+
def resolve_codec_weight_dtype(codec_weight_dtype: str) -> torch.dtype:
|
| 98 |
+
key = str(codec_weight_dtype).lower()
|
| 99 |
+
if key not in SUPPORTED_CODEC_WEIGHT_DTYPES:
|
| 100 |
+
raise ValueError(
|
| 101 |
+
"Unsupported codec_weight_dtype="
|
| 102 |
+
f"{codec_weight_dtype!r}. Expected one of {sorted(SUPPORTED_CODEC_WEIGHT_DTYPES)}."
|
| 103 |
+
)
|
| 104 |
+
return SUPPORTED_CODEC_WEIGHT_DTYPES[key]
|
| 105 |
+
|
| 106 |
+
|
| 107 |
@contextmanager
|
| 108 |
def disable_cuda_autocast():
|
| 109 |
with torch.autocast(device_type="cuda", enabled=False):
|
|
|
|
| 747 |
)
|
| 748 |
|
| 749 |
def _supports_flash_attention(self, device: torch.device, dtype: torch.dtype) -> bool:
|
| 750 |
+
return HAS_FLASH_ATTN and device.type == "cuda" and dtype == torch.bfloat16
|
| 751 |
|
| 752 |
def _get_backend_check_dtype(self, x: torch.Tensor) -> torch.dtype:
|
| 753 |
if x.device.type != "cuda":
|
|
|
|
| 1810 |
self.attention_implementation = config.attention_implementation
|
| 1811 |
self.compute_dtype_name = config.compute_dtype
|
| 1812 |
self.compute_dtype = resolve_compute_dtype(config.compute_dtype)
|
| 1813 |
+
self.codec_weight_dtype_name = canonicalize_codec_weight_dtype(
|
| 1814 |
+
getattr(config, "codec_weight_dtype", "fp32")
|
| 1815 |
+
)
|
| 1816 |
|
| 1817 |
encoder_context_durations = [
|
| 1818 |
float(module_kwargs.get("context_duration", config.causal_transformer_context_duration))
|
|
|
|
| 1883 |
|
| 1884 |
self.post_init()
|
| 1885 |
|
| 1886 |
+
@classmethod
|
| 1887 |
+
def from_pretrained(cls, pretrained_model_name_or_path, *model_args, **kwargs):
|
| 1888 |
+
codec_weight_dtype = kwargs.pop("codec_weight_dtype", None)
|
| 1889 |
+
explicit_torch_dtype = kwargs.get("torch_dtype", None)
|
| 1890 |
+
model = super().from_pretrained(pretrained_model_name_or_path, *model_args, **kwargs)
|
| 1891 |
+
if codec_weight_dtype is None:
|
| 1892 |
+
codec_weight_dtype = getattr(model.config, "codec_weight_dtype", "fp32")
|
| 1893 |
+
if explicit_torch_dtype is not None and canonicalize_codec_weight_dtype(codec_weight_dtype) != "fp32":
|
| 1894 |
+
logger.warning(
|
| 1895 |
+
"`torch_dtype` was passed while `codec_weight_dtype` is enabled. "
|
| 1896 |
+
"Prefer leaving codec `torch_dtype` unset so the fp32 quantizer weights are loaded without precision loss."
|
| 1897 |
+
)
|
| 1898 |
+
model.set_codec_weight_dtype(codec_weight_dtype)
|
| 1899 |
+
return model
|
| 1900 |
+
|
| 1901 |
def _start_streaming(self, batch_size: int):
|
| 1902 |
"""Start streaming mode for all modules."""
|
| 1903 |
|
|
|
|
| 1986 |
if device.type == "cuda" and self.compute_dtype is not None:
|
| 1987 |
with torch.autocast(device_type="cuda", dtype=self.compute_dtype):
|
| 1988 |
yield
|
| 1989 |
+
elif device.type == "cpu" and self.compute_dtype is torch.bfloat16:
|
| 1990 |
+
with torch.autocast(device_type="cpu", dtype=self.compute_dtype):
|
| 1991 |
+
yield
|
| 1992 |
else:
|
| 1993 |
yield
|
| 1994 |
|
|
|
|
| 2001 |
def set_compute_dtype(self, compute_dtype: str) -> None:
|
| 2002 |
self.compute_dtype_name = compute_dtype
|
| 2003 |
self.compute_dtype = resolve_compute_dtype(compute_dtype)
|
| 2004 |
+
self.config.compute_dtype = compute_dtype
|
| 2005 |
+
|
| 2006 |
+
def set_codec_weight_dtype(self, codec_weight_dtype: str) -> None:
|
| 2007 |
+
codec_weight_dtype = canonicalize_codec_weight_dtype(codec_weight_dtype)
|
| 2008 |
+
weight_dtype = resolve_codec_weight_dtype(codec_weight_dtype)
|
| 2009 |
+
|
| 2010 |
+
self.encoder.to(dtype=weight_dtype)
|
| 2011 |
+
self.decoder.to(dtype=weight_dtype)
|
| 2012 |
+
|
| 2013 |
+
# Quantizer decode/encode intentionally disables autocast and builds fp32 intermediates.
|
| 2014 |
+
# Keeping it fp32 avoids fp32-input/bf16-bias mismatches and preserves codebook numerics.
|
| 2015 |
+
self.quantizer.to(dtype=torch.float32)
|
| 2016 |
+
|
| 2017 |
+
self.codec_weight_dtype_name = codec_weight_dtype
|
| 2018 |
+
self.config.codec_weight_dtype = codec_weight_dtype
|
| 2019 |
+
if codec_weight_dtype != "fp32" and self.compute_dtype is None:
|
| 2020 |
+
self.set_compute_dtype(codec_weight_dtype)
|
| 2021 |
+
|
| 2022 |
+
def get_codec_dtype_summary(self) -> dict[str, str]:
|
| 2023 |
+
def _first_param_dtype(module: nn.Module) -> str:
|
| 2024 |
+
for param in module.parameters():
|
| 2025 |
+
return str(param.dtype)
|
| 2026 |
+
return "no_params"
|
| 2027 |
+
|
| 2028 |
+
return {
|
| 2029 |
+
"encoder": _first_param_dtype(self.encoder),
|
| 2030 |
+
"decoder": _first_param_dtype(self.decoder),
|
| 2031 |
+
"quantizer": _first_param_dtype(self.quantizer),
|
| 2032 |
+
"compute_dtype": self.compute_dtype_name,
|
| 2033 |
+
"codec_weight_dtype": self.codec_weight_dtype_name,
|
| 2034 |
+
}
|
| 2035 |
|
| 2036 |
def _prepare_waveform_batch(
|
| 2037 |
self,
|
|
|
|
| 2201 |
|
| 2202 |
quantizer = cast(MossAudioTokenizerResidualVQ | MossAudioTokenizerResidualLFQ, self.quantizer)
|
| 2203 |
_, audio_codes, audio_codes_lengths = quantizer(encoder_hidden_states.float(), encoder_hidden_lengths, n_quantizers)
|
| 2204 |
+
max_valid_length = int(audio_codes_lengths.max().item()) if audio_codes_lengths.numel() > 0 else 0
|
| 2205 |
+
audio_codes = audio_codes[:, :, :max_valid_length]
|
| 2206 |
+
encoder_hidden_states = encoder_hidden_states[:, :, :max_valid_length]
|
| 2207 |
|
| 2208 |
return MossAudioTokenizerEncoderOutput(
|
| 2209 |
audio_codes=audio_codes,
|