初始化项目,由ModelHub XC社区提供模型

Model: sakares/wav2vec2-large-xlsr-thai-demo
Source: Original Platform
This commit is contained in:
ModelHub XC
2026-05-28 11:11:19 +08:00
commit 875c4e1fac
12 changed files with 394 additions and 0 deletions

16
.gitattributes vendored Normal file
View File

@@ -0,0 +1,16 @@
*.bin.* filter=lfs diff=lfs merge=lfs -text
*.lfs.* filter=lfs diff=lfs merge=lfs -text
*.bin filter=lfs diff=lfs merge=lfs -text
*.h5 filter=lfs diff=lfs merge=lfs -text
*.tflite filter=lfs diff=lfs merge=lfs -text
*.tar.gz filter=lfs diff=lfs merge=lfs -text
*.ot filter=lfs diff=lfs merge=lfs -text
*.onnx filter=lfs diff=lfs merge=lfs -text
*.arrow filter=lfs diff=lfs merge=lfs -text
*.ftz filter=lfs diff=lfs merge=lfs -text
*.joblib filter=lfs diff=lfs merge=lfs -text
*.model filter=lfs diff=lfs merge=lfs -text
*.msgpack filter=lfs diff=lfs merge=lfs -text
*.pb filter=lfs diff=lfs merge=lfs -text
*.pt filter=lfs diff=lfs merge=lfs -text
*.pth filter=lfs diff=lfs merge=lfs -text

137
README.md Normal file
View File

@@ -0,0 +1,137 @@
---
language: th
datasets:
- common_voice
tags:
- audio
- automatic-speech-recognition
- speech
- xlsr-fine-tuning-week
license: apache-2.0
model-index:
- name: XLSR Wav2Vec2 Large Thai by Sakares
results:
- task:
name: Speech Recognition
type: automatic-speech-recognition
dataset:
name: Common Voice th
type: common_voice
args: th
metrics:
- name: Test WER
type: wer
value: 44.46
---
# Wav2Vec2-Large-XLSR-53-Thai
Fine-tuned [facebook/wav2vec2-large-xlsr-53](https://huggingface.co/facebook/wav2vec2-large-xlsr-53) in Thai using the [Common Voice](https://huggingface.co/datasets/common_voice)
When using this model, make sure that your speech input is sampled at 16kHz.
## Usage
The model can be used directly (without a language model) as follows:
```python
import torch
import torchaudio
from datasets import load_dataset
from transformers import Wav2Vec2ForCTC, Wav2Vec2Processor
from pythainlp.tokenize import word_tokenize
test_dataset = load_dataset("common_voice", "th", split="test[:2%]")
processor = Wav2Vec2Processor.from_pretrained("sakares/wav2vec2-large-xlsr-thai-demo")
model = Wav2Vec2ForCTC.from_pretrained("sakares/wav2vec2-large-xlsr-thai-demo")
resampler = torchaudio.transforms.Resample(48_000, 16_000)
## For Thai NLP Library, please feel free to check https://pythainlp.github.io/docs/2.2/api/tokenize.html
def th_tokenize(batch):
batch["sentence"] = " ".join(word_tokenize(batch["sentence"], engine="newmm"))
return batch
# Preprocessing the datasets.
# We need to read the aduio files as arrays
def speech_file_to_array_fn(batch):
speech_array, sampling_rate = torchaudio.load(batch["path"])
batch["speech"] = resampler(speech_array).squeeze().numpy()
return batch
test_dataset = test_dataset.map(speech_file_to_array_fn).map(th_tokenize)
inputs = processor(test_dataset["speech"][:2], sampling_rate=16_000, return_tensors="pt", padding=True)
with torch.no_grad():
logits = model(inputs.input_values, attention_mask=inputs.attention_mask).logits
predicted_ids = torch.argmax(logits, dim=-1)
print("Prediction:", processor.batch_decode(predicted_ids))
print("Reference:", test_dataset["sentence"][:2])
```
Usage script [here](https://colab.research.google.com/drive/1w0VywsBtjrO2pHHPmiPugYI9yeF8nUKg?usp=sharing)
## Evaluation
The model can be evaluated as follows on the {language} test data of Common Voice.
```python
import torch
import torchaudio
from datasets import load_dataset, load_metric
from transformers import Wav2Vec2ForCTC, Wav2Vec2Processor
from pythainlp.tokenize import word_tokenize
import re
test_dataset = load_dataset("common_voice", "th", split="test")
wer = load_metric("wer")
processor = Wav2Vec2Processor.from_pretrained("sakares/wav2vec2-large-xlsr-thai-demo")
model = Wav2Vec2ForCTC.from_pretrained("sakares/wav2vec2-large-xlsr-thai-demo")
model.to("cuda")
chars_to_ignore_regex = '[\,\?\.\!\-\;\:\"\“]'
resampler = torchaudio.transforms.Resample(48_000, 16_000)
## For Thai NLP Library, please feel free to check https://pythainlp.github.io/docs/2.2/api/tokenize.html
def th_tokenize(batch):
batch["sentence"] = " ".join(word_tokenize(batch["sentence"], engine="newmm"))
return batch
# Preprocessing the datasets.
# We need to read the aduio files as arrays
def speech_file_to_array_fn(batch):
batch["sentence"] = re.sub(chars_to_ignore_regex, '', batch["sentence"]).lower()
speech_array, sampling_rate = torchaudio.load(batch["path"])
batch["speech"] = resampler(speech_array).squeeze().numpy()
return batch
test_dataset = test_dataset.map(speech_file_to_array_fn).map(th_tokenize)
# Preprocessing the datasets.
# We need to read the aduio files as arrays
def evaluate(batch):
inputs = processor(batch["speech"], sampling_rate=16_000, return_tensors="pt", padding=True)
with torch.no_grad():
logits = model(inputs.input_values.to("cuda"), attention_mask=inputs.attention_mask.to("cuda")).logits
pred_ids = torch.argmax(logits, dim=-1)
batch["pred_strings"] = processor.batch_decode(pred_ids)
return batch
result = test_dataset.map(evaluate, batched=True, batch_size=8)
print("WER: {:2f}".format(100 * wer.compute(predictions=result["pred_strings"], references=result["sentence"])))
```
**Test Result**: 44.46 %
Evaluate script [here](https://colab.research.google.com/drive/1WZGtHKWXBztRsuXHIdebf6uoAsp7rTnK?usp=sharing)
## Training
The Common Voice `train`, `validation` datasets were used for training.
The script used for training can be found [here](https://colab.research.google.com/drive/18oUbeZgBGSkz16zC_WOa154QZOdmvjyt?usp=sharing)

76
config.json Normal file
View File

@@ -0,0 +1,76 @@
{
"_name_or_path": "facebook/wav2vec2-large-xlsr-53",
"activation_dropout": 0.0,
"apply_spec_augment": true,
"architectures": [
"Wav2Vec2ForCTC"
],
"attention_dropout": 0.1,
"bos_token_id": 1,
"conv_bias": true,
"conv_dim": [
512,
512,
512,
512,
512,
512,
512
],
"conv_kernel": [
10,
3,
3,
3,
3,
2,
2
],
"conv_stride": [
5,
2,
2,
2,
2,
2,
2
],
"ctc_loss_reduction": "mean",
"ctc_zero_infinity": false,
"do_stable_layer_norm": true,
"eos_token_id": 2,
"feat_extract_activation": "gelu",
"feat_extract_dropout": 0.0,
"feat_extract_norm": "layer",
"feat_proj_dropout": 0.0,
"final_dropout": 0.0,
"gradient_checkpointing": true,
"hidden_act": "gelu",
"hidden_dropout": 0.1,
"hidden_size": 1024,
"initializer_range": 0.02,
"intermediate_size": 4096,
"layer_norm_eps": 1e-05,
"layerdrop": 0.1,
"mask_channel_length": 10,
"mask_channel_min_space": 1,
"mask_channel_other": 0.0,
"mask_channel_prob": 0.0,
"mask_channel_selection": "static",
"mask_feature_length": 10,
"mask_feature_prob": 0.0,
"mask_time_length": 10,
"mask_time_min_space": 1,
"mask_time_other": 0.0,
"mask_time_prob": 0.05,
"mask_time_selection": "static",
"model_type": "wav2vec2",
"num_attention_heads": 16,
"num_conv_pos_embedding_groups": 16,
"num_conv_pos_embeddings": 128,
"num_feat_extract_layers": 7,
"num_hidden_layers": 24,
"pad_token_id": 70,
"transformers_version": "4.4.0",
"vocab_size": 71
}

3
optimizer.pt Normal file
View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9cb1f03e6996f45067b37846665462c9469495843102ce187588b897e28a7f4e
size 2490659335

8
preprocessor_config.json Normal file
View File

@@ -0,0 +1,8 @@
{
"do_normalize": true,
"feature_size": 1,
"padding_side": "right",
"padding_value": 0.0,
"return_attention_mask": true,
"sampling_rate": 16000
}

3
pytorch_model.bin Normal file
View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8cf9e30486947e5ed90fbee04baf77edce0daadf0effb971a783e7eee53f6215
size 1262224919

3
scheduler.pt Normal file
View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4eadfc8ad40d25eb205d452eb44ca33a8d304d9199be7da405ad3378ff843c81
size 623

1
special_tokens_map.json Normal file
View File

@@ -0,0 +1 @@
{"bos_token": "<s>", "eos_token": "</s>", "unk_token": "[UNK]", "pad_token": "[PAD]"}

1
tokenizer_config.json Normal file
View File

@@ -0,0 +1 @@
{"unk_token": "[UNK]", "bos_token": "<s>", "eos_token": "</s>", "pad_token": "[PAD]", "do_lower_case": false, "word_delimiter_token": "|"}

142
trainer_state.json Normal file
View File

@@ -0,0 +1,142 @@
{
"best_metric": null,
"best_model_checkpoint": null,
"epoch": 23.83828382838284,
"global_step": 3600,
"is_hyper_param_search": false,
"is_local_process_zero": true,
"is_world_process_zero": true,
"log_history": [
{
"epoch": 2.65,
"learning_rate": 0.00023999999999999998,
"loss": 6.5741,
"step": 400
},
{
"epoch": 2.65,
"eval_loss": 3.4423439502716064,
"eval_runtime": 231.306,
"eval_samples_per_second": 9.459,
"eval_wer": 1.0,
"step": 400
},
{
"epoch": 5.3,
"learning_rate": 0.0002711907810499359,
"loss": 1.6231,
"step": 800
},
{
"epoch": 5.3,
"eval_loss": 0.6918022036552429,
"eval_runtime": 234.8428,
"eval_samples_per_second": 9.317,
"eval_wer": 0.7177260916407884,
"step": 800
},
{
"epoch": 7.94,
"learning_rate": 0.00023277848911651725,
"loss": 0.5103,
"step": 1200
},
{
"epoch": 7.94,
"eval_loss": 0.5981740951538086,
"eval_runtime": 233.6413,
"eval_samples_per_second": 9.365,
"eval_wer": 0.6444007858546169,
"step": 1200
},
{
"epoch": 10.59,
"learning_rate": 0.0001943661971830986,
"loss": 0.316,
"step": 1600
},
{
"epoch": 10.59,
"eval_loss": 0.6127611398696899,
"eval_runtime": 239.3303,
"eval_samples_per_second": 9.142,
"eval_wer": 0.6053615564991445,
"step": 1600
},
{
"epoch": 13.24,
"learning_rate": 0.0001559539052496799,
"loss": 0.227,
"step": 2000
},
{
"epoch": 13.24,
"eval_loss": 0.6392495036125183,
"eval_runtime": 236.7294,
"eval_samples_per_second": 9.243,
"eval_wer": 0.5767158882058432,
"step": 2000
},
{
"epoch": 15.89,
"learning_rate": 0.00011754161331626119,
"loss": 0.1783,
"step": 2400
},
{
"epoch": 15.89,
"eval_loss": 0.6448690891265869,
"eval_runtime": 240.8912,
"eval_samples_per_second": 9.083,
"eval_wer": 0.5625831801761836,
"step": 2400
},
{
"epoch": 18.54,
"learning_rate": 7.91293213828425e-05,
"loss": 0.1346,
"step": 2800
},
{
"epoch": 18.54,
"eval_loss": 0.6509573459625244,
"eval_runtime": 238.9168,
"eval_samples_per_second": 9.158,
"eval_wer": 0.5524431206033336,
"step": 2800
},
{
"epoch": 21.19,
"learning_rate": 4.071702944942381e-05,
"loss": 0.1149,
"step": 3200
},
{
"epoch": 21.19,
"eval_loss": 0.7118895053863525,
"eval_runtime": 239.1827,
"eval_samples_per_second": 9.148,
"eval_wer": 0.5582736548577223,
"step": 3200
},
{
"epoch": 23.84,
"learning_rate": 2.3047375160051214e-06,
"loss": 0.1024,
"step": 3600
},
{
"epoch": 23.84,
"eval_loss": 0.6984374523162842,
"eval_runtime": 239.7197,
"eval_samples_per_second": 9.127,
"eval_wer": 0.5488307243805057,
"step": 3600
}
],
"max_steps": 3624,
"num_train_epochs": 24,
"total_flos": 1.4828294022260212e+19,
"trial_name": null,
"trial_params": null
}

3
training_args.bin Normal file
View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:172c59484ed932416417e6a198f03373837732beb2793acc906d873aa5e63514
size 2351

1
vocab.json Normal file
View File

@@ -0,0 +1 @@
{"ู": 0, "ั": 1, "ะ": 2, "ฆ": 3, "ำ": 4, "ึ": 5, "๋": 6, "ส": 7, "์": 8, "ฮ": 9, "ค": 10, "่": 11, "ผ": 12, "ศ": 13, "จ": 14, "ล": 15, "ฒ": 16, "ป": 17, "ม": 18, "็": 19, "": 20, "ง": 21, "ํ": 22, "ฝ": 23, "ื": 24, "โ": 25, "ห": 26, "้": 27, "ษ": 29, "ๆ": 30, "า": 31, "ฟ": 32, "แ": 33, "ด": 34, "ท": 35, "ใ": 36, "ณ": 37, "ฬ": 38, "ไ": 39, "ๅ": 40, "อ": 41, "ี": 42, "๊": 43, "บ": 44, "ย": 45, "ิ": 46, "ฉ": 47, "ภ": 48, "ฏ": 49, "ข": 50, "ก": 51, "'": 52, "เ": 53, "พ": 54, "ฐ": 55, "ญ": 56, "น": 57, "ธ": 58, "ถ": 59, "ซ": 60, "ร": 61, "ฤ": 62, "ช": 63, "ุ": 64, "ต": 65, "ฑ": 66, "ฎ": 67, "ว": 68, "|": 28, "[UNK]": 69, "[PAD]": 70}