StevenLimcorn
commited on
Commit
•
6b4e08d
1
Parent(s):
7535d1d
Training in progress, step 500
Browse files- .gitignore +1 -0
- added_tokens.json +1 -0
- config.json +107 -0
- nohup.out +0 -0
- preprocessor_config.json +9 -0
- pytorch_model.bin +3 -0
- run.sh +37 -0
- run_speech_recognition_ctc.py +737 -0
- runs/Feb06_11-36-42_job-a1cf84c8-7d28-46cd-9f0a-e09d16d4a1cb/1644147756.2090228/events.out.tfevents.1644147756.job-a1cf84c8-7d28-46cd-9f0a-e09d16d4a1cb +3 -0
- runs/Feb06_11-36-42_job-a1cf84c8-7d28-46cd-9f0a-e09d16d4a1cb/events.out.tfevents.1644147756.job-a1cf84c8-7d28-46cd-9f0a-e09d16d4a1cb +3 -0
- special_tokens_map.json +1 -0
- tokenizer_config.json +1 -0
- training_args.bin +3 -0
- vocab.json +1 -0
.gitignore
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
checkpoint-*/
|
added_tokens.json
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
{"<s>": 2656, "</s>": 2657}
|
config.json
ADDED
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"_name_or_path": "facebook/wav2vec2-xls-r-300m",
|
3 |
+
"activation_dropout": 0.1,
|
4 |
+
"adapter_kernel_size": 3,
|
5 |
+
"adapter_stride": 2,
|
6 |
+
"add_adapter": false,
|
7 |
+
"apply_spec_augment": true,
|
8 |
+
"architectures": [
|
9 |
+
"Wav2Vec2ForCTC"
|
10 |
+
],
|
11 |
+
"attention_dropout": 0.0,
|
12 |
+
"bos_token_id": 1,
|
13 |
+
"classifier_proj_size": 256,
|
14 |
+
"codevector_dim": 768,
|
15 |
+
"contrastive_logits_temperature": 0.1,
|
16 |
+
"conv_bias": true,
|
17 |
+
"conv_dim": [
|
18 |
+
512,
|
19 |
+
512,
|
20 |
+
512,
|
21 |
+
512,
|
22 |
+
512,
|
23 |
+
512,
|
24 |
+
512
|
25 |
+
],
|
26 |
+
"conv_kernel": [
|
27 |
+
10,
|
28 |
+
3,
|
29 |
+
3,
|
30 |
+
3,
|
31 |
+
3,
|
32 |
+
2,
|
33 |
+
2
|
34 |
+
],
|
35 |
+
"conv_stride": [
|
36 |
+
5,
|
37 |
+
2,
|
38 |
+
2,
|
39 |
+
2,
|
40 |
+
2,
|
41 |
+
2,
|
42 |
+
2
|
43 |
+
],
|
44 |
+
"ctc_loss_reduction": "mean",
|
45 |
+
"ctc_zero_infinity": false,
|
46 |
+
"diversity_loss_weight": 0.1,
|
47 |
+
"do_stable_layer_norm": true,
|
48 |
+
"eos_token_id": 2,
|
49 |
+
"feat_extract_activation": "gelu",
|
50 |
+
"feat_extract_dropout": 0.0,
|
51 |
+
"feat_extract_norm": "layer",
|
52 |
+
"feat_proj_dropout": 0.0,
|
53 |
+
"feat_quantizer_dropout": 0.0,
|
54 |
+
"final_dropout": 0.0,
|
55 |
+
"hidden_act": "gelu",
|
56 |
+
"hidden_dropout": 0.0,
|
57 |
+
"hidden_size": 1024,
|
58 |
+
"initializer_range": 0.02,
|
59 |
+
"intermediate_size": 4096,
|
60 |
+
"layer_norm_eps": 1e-05,
|
61 |
+
"layerdrop": 0.0,
|
62 |
+
"mask_feature_length": 64,
|
63 |
+
"mask_feature_min_masks": 0,
|
64 |
+
"mask_feature_prob": 0.25,
|
65 |
+
"mask_time_length": 10,
|
66 |
+
"mask_time_min_masks": 2,
|
67 |
+
"mask_time_prob": 0.75,
|
68 |
+
"model_type": "wav2vec2",
|
69 |
+
"num_adapter_layers": 3,
|
70 |
+
"num_attention_heads": 16,
|
71 |
+
"num_codevector_groups": 2,
|
72 |
+
"num_codevectors_per_group": 320,
|
73 |
+
"num_conv_pos_embedding_groups": 16,
|
74 |
+
"num_conv_pos_embeddings": 128,
|
75 |
+
"num_feat_extract_layers": 7,
|
76 |
+
"num_hidden_layers": 24,
|
77 |
+
"num_negatives": 100,
|
78 |
+
"output_hidden_size": 1024,
|
79 |
+
"pad_token_id": 2655,
|
80 |
+
"proj_codevector_dim": 768,
|
81 |
+
"tdnn_dilation": [
|
82 |
+
1,
|
83 |
+
2,
|
84 |
+
3,
|
85 |
+
1,
|
86 |
+
1
|
87 |
+
],
|
88 |
+
"tdnn_dim": [
|
89 |
+
512,
|
90 |
+
512,
|
91 |
+
512,
|
92 |
+
512,
|
93 |
+
1500
|
94 |
+
],
|
95 |
+
"tdnn_kernel": [
|
96 |
+
5,
|
97 |
+
3,
|
98 |
+
3,
|
99 |
+
1,
|
100 |
+
1
|
101 |
+
],
|
102 |
+
"torch_dtype": "float32",
|
103 |
+
"transformers_version": "4.17.0.dev0",
|
104 |
+
"use_weighted_layer_sum": false,
|
105 |
+
"vocab_size": 2658,
|
106 |
+
"xvector_output_dim": 512
|
107 |
+
}
|
nohup.out
ADDED
The diff for this file is too large to render.
See raw diff
|
|
preprocessor_config.json
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"do_normalize": true,
|
3 |
+
"feature_extractor_type": "Wav2Vec2FeatureExtractor",
|
4 |
+
"feature_size": 1,
|
5 |
+
"padding_side": "right",
|
6 |
+
"padding_value": 0,
|
7 |
+
"return_attention_mask": true,
|
8 |
+
"sampling_rate": 16000
|
9 |
+
}
|
pytorch_model.bin
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:0b16dbf173b2ee35a78f20078db7ee28a0b7cf318fc5823f5cc213d0b7152057
|
3 |
+
size 1272821553
|
run.sh
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
python run_speech_recognition_ctc.py \
|
2 |
+
--dataset_name="common_voice" \
|
3 |
+
--model_name_or_path="facebook/wav2vec2-xls-r-300m" \
|
4 |
+
--dataset_config_name="zh-TW" \
|
5 |
+
--output_dir="./" \
|
6 |
+
--overwrite_output_dir \
|
7 |
+
--num_train_epochs="100" \
|
8 |
+
--per_device_train_batch_size="8" \
|
9 |
+
--per_device_eval_batch_size="8" \
|
10 |
+
--gradient_accumulation_steps="4" \
|
11 |
+
--learning_rate="7.5e-5" \
|
12 |
+
--warmup_steps="2000" \
|
13 |
+
--length_column_name="input_length" \
|
14 |
+
--max_duration_in_seconds="7" \
|
15 |
+
--max_eval_samples="3000" \
|
16 |
+
--evaluation_strategy="steps" \
|
17 |
+
--text_column_name="sentence" \
|
18 |
+
--chars_to_ignore , ? . ! \- \; \: \" “ % ‘ ” � — ’ … – ! - : – 。 》 , ) , ? ; ~ ~ … ︰ , ( 」 ‧ 《 ﹔ 、 — / , 「 ﹖ · \
|
19 |
+
--save_steps="500" \
|
20 |
+
--eval_steps="500" \
|
21 |
+
--logging_steps="100" \
|
22 |
+
--layerdrop="0.0" \
|
23 |
+
--activation_dropout="0.1" \
|
24 |
+
--save_total_limit="3" \
|
25 |
+
--freeze_feature_encoder \
|
26 |
+
--feat_proj_dropout="0.0" \
|
27 |
+
--mask_time_prob="0.75" \
|
28 |
+
--mask_time_length="10" \
|
29 |
+
--mask_feature_prob="0.25" \
|
30 |
+
--mask_feature_length="64" \
|
31 |
+
--gradient_checkpointing \
|
32 |
+
--use_auth_token \
|
33 |
+
--fp16 \
|
34 |
+
--group_by_length \
|
35 |
+
--do_train --do_eval \
|
36 |
+
--report_to="tensorboard" \
|
37 |
+
--push_to_hub
|
run_speech_recognition_ctc.py
ADDED
@@ -0,0 +1,737 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env python
|
2 |
+
# coding=utf-8
|
3 |
+
# Copyright 2021 The HuggingFace Inc. team. All rights reserved.
|
4 |
+
#
|
5 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6 |
+
# you may not use this file except in compliance with the License.
|
7 |
+
# You may obtain a copy of the License at
|
8 |
+
#
|
9 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10 |
+
#
|
11 |
+
# Unless required by applicable law or agreed to in writing, software
|
12 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14 |
+
# See the License for the specific language governing permissions and
|
15 |
+
|
16 |
+
""" Fine-tuning a 🤗 Transformers CTC model for automatic speech recognition"""
|
17 |
+
|
18 |
+
import functools
|
19 |
+
import json
|
20 |
+
import logging
|
21 |
+
import os
|
22 |
+
import re
|
23 |
+
import sys
|
24 |
+
import warnings
|
25 |
+
from dataclasses import dataclass, field
|
26 |
+
from typing import Dict, List, Optional, Union
|
27 |
+
|
28 |
+
import datasets
|
29 |
+
import numpy as np
|
30 |
+
import torch
|
31 |
+
from datasets import DatasetDict, load_dataset, load_metric
|
32 |
+
|
33 |
+
import transformers
|
34 |
+
from transformers import (
|
35 |
+
AutoConfig,
|
36 |
+
AutoFeatureExtractor,
|
37 |
+
AutoModelForCTC,
|
38 |
+
AutoProcessor,
|
39 |
+
AutoTokenizer,
|
40 |
+
HfArgumentParser,
|
41 |
+
Trainer,
|
42 |
+
TrainingArguments,
|
43 |
+
Wav2Vec2Processor,
|
44 |
+
set_seed,
|
45 |
+
)
|
46 |
+
from transformers.trainer_utils import get_last_checkpoint, is_main_process
|
47 |
+
from transformers.utils import check_min_version
|
48 |
+
from transformers.utils.versions import require_version
|
49 |
+
|
50 |
+
|
51 |
+
# Will error if the minimal version of Transformers is not installed. Remove at your own risks.
|
52 |
+
check_min_version("4.17.0.dev0")
|
53 |
+
|
54 |
+
require_version("datasets>=1.13.3", "To fix: pip install -r examples/pytorch/text-classification/requirements.txt")
|
55 |
+
|
56 |
+
|
57 |
+
logger = logging.getLogger(__name__)
|
58 |
+
|
59 |
+
|
60 |
+
def list_field(default=None, metadata=None):
|
61 |
+
return field(default_factory=lambda: default, metadata=metadata)
|
62 |
+
|
63 |
+
|
64 |
+
@dataclass
|
65 |
+
class ModelArguments:
|
66 |
+
"""
|
67 |
+
Arguments pertaining to which model/config/tokenizer we are going to fine-tune from.
|
68 |
+
"""
|
69 |
+
|
70 |
+
model_name_or_path: str = field(
|
71 |
+
metadata={"help": "Path to pretrained model or model identifier from huggingface.co/models"}
|
72 |
+
)
|
73 |
+
tokenizer_name_or_path: Optional[str] = field(
|
74 |
+
default=None,
|
75 |
+
metadata={"help": "Path to pretrained tokenizer or tokenizer identifier from huggingface.co/models"},
|
76 |
+
)
|
77 |
+
cache_dir: Optional[str] = field(
|
78 |
+
default=None,
|
79 |
+
metadata={"help": "Where do you want to store the pretrained models downloaded from huggingface.co"},
|
80 |
+
)
|
81 |
+
freeze_feature_encoder: bool = field(
|
82 |
+
default=True, metadata={"help": "Whether to freeze the feature encoder layers of the model."}
|
83 |
+
)
|
84 |
+
attention_dropout: float = field(
|
85 |
+
default=0.0, metadata={"help": "The dropout ratio for the attention probabilities."}
|
86 |
+
)
|
87 |
+
activation_dropout: float = field(
|
88 |
+
default=0.0, metadata={"help": "The dropout ratio for activations inside the fully connected layer."}
|
89 |
+
)
|
90 |
+
feat_proj_dropout: float = field(default=0.0, metadata={"help": "The dropout ratio for the projected features."})
|
91 |
+
hidden_dropout: float = field(
|
92 |
+
default=0.0,
|
93 |
+
metadata={
|
94 |
+
"help": "The dropout probability for all fully connected layers in the embeddings, encoder, and pooler."
|
95 |
+
},
|
96 |
+
)
|
97 |
+
final_dropout: float = field(
|
98 |
+
default=0.0,
|
99 |
+
metadata={"help": "The dropout probability for the final projection layer."},
|
100 |
+
)
|
101 |
+
mask_time_prob: float = field(
|
102 |
+
default=0.05,
|
103 |
+
metadata={
|
104 |
+
"help": "Probability of each feature vector along the time axis to be chosen as the start of the vector"
|
105 |
+
"span to be masked. Approximately ``mask_time_prob * sequence_length // mask_time_length`` feature"
|
106 |
+
"vectors will be masked along the time axis."
|
107 |
+
},
|
108 |
+
)
|
109 |
+
mask_time_length: int = field(
|
110 |
+
default=10,
|
111 |
+
metadata={"help": "Length of vector span to mask along the time axis."},
|
112 |
+
)
|
113 |
+
mask_feature_prob: float = field(
|
114 |
+
default=0.0,
|
115 |
+
metadata={
|
116 |
+
"help": "Probability of each feature vector along the feature axis to be chosen as the start of the vector"
|
117 |
+
"span to be masked. Approximately ``mask_feature_prob * sequence_length // mask_feature_length`` feature bins will be masked along the time axis."
|
118 |
+
},
|
119 |
+
)
|
120 |
+
mask_feature_length: int = field(
|
121 |
+
default=10,
|
122 |
+
metadata={"help": "Length of vector span to mask along the feature axis."},
|
123 |
+
)
|
124 |
+
layerdrop: float = field(default=0.0, metadata={"help": "The LayerDrop probability."})
|
125 |
+
ctc_loss_reduction: Optional[str] = field(
|
126 |
+
default="mean", metadata={"help": "The way the ctc loss should be reduced. Should be one of 'mean' or 'sum'."}
|
127 |
+
)
|
128 |
+
|
129 |
+
|
130 |
+
@dataclass
|
131 |
+
class DataTrainingArguments:
|
132 |
+
"""
|
133 |
+
Arguments pertaining to what data we are going to input our model for training and eval.
|
134 |
+
|
135 |
+
Using `HfArgumentParser` we can turn this class
|
136 |
+
into argparse arguments to be able to specify them on
|
137 |
+
the command line.
|
138 |
+
"""
|
139 |
+
|
140 |
+
dataset_name: str = field(
|
141 |
+
metadata={"help": "The configuration name of the dataset to use (via the datasets library)."}
|
142 |
+
)
|
143 |
+
dataset_config_name: str = field(
|
144 |
+
default=None, metadata={"help": "The configuration name of the dataset to use (via the datasets library)."}
|
145 |
+
)
|
146 |
+
train_split_name: str = field(
|
147 |
+
default="train+validation",
|
148 |
+
metadata={
|
149 |
+
"help": "The name of the training data set split to use (via the datasets library). Defaults to 'train+validation'"
|
150 |
+
},
|
151 |
+
)
|
152 |
+
eval_split_name: str = field(
|
153 |
+
default="test",
|
154 |
+
metadata={
|
155 |
+
"help": "The name of the evaluation data set split to use (via the datasets library). Defaults to 'test'"
|
156 |
+
},
|
157 |
+
)
|
158 |
+
audio_column_name: str = field(
|
159 |
+
default="audio",
|
160 |
+
metadata={"help": "The name of the dataset column containing the audio data. Defaults to 'audio'"},
|
161 |
+
)
|
162 |
+
text_column_name: str = field(
|
163 |
+
default="text",
|
164 |
+
metadata={"help": "The name of the dataset column containing the text data. Defaults to 'text'"},
|
165 |
+
)
|
166 |
+
overwrite_cache: bool = field(
|
167 |
+
default=False, metadata={"help": "Overwrite the cached preprocessed datasets or not."}
|
168 |
+
)
|
169 |
+
preprocessing_num_workers: Optional[int] = field(
|
170 |
+
default=None,
|
171 |
+
metadata={"help": "The number of processes to use for the preprocessing."},
|
172 |
+
)
|
173 |
+
max_train_samples: Optional[int] = field(
|
174 |
+
default=None,
|
175 |
+
metadata={
|
176 |
+
"help": "For debugging purposes or quicker training, truncate the number of training examples to this "
|
177 |
+
"value if set."
|
178 |
+
},
|
179 |
+
)
|
180 |
+
max_eval_samples: Optional[int] = field(
|
181 |
+
default=None,
|
182 |
+
metadata={
|
183 |
+
"help": "For debugging purposes or quicker training, truncate the number of validation examples to this "
|
184 |
+
"value if set."
|
185 |
+
},
|
186 |
+
)
|
187 |
+
chars_to_ignore: Optional[List[str]] = list_field(
|
188 |
+
default=None,
|
189 |
+
metadata={"help": "A list of characters to remove from the transcripts."},
|
190 |
+
)
|
191 |
+
eval_metrics: List[str] = list_field(
|
192 |
+
default=["wer", "cer"],
|
193 |
+
metadata={"help": "A list of metrics the model should be evaluated on. E.g. `'wer cer'`"},
|
194 |
+
)
|
195 |
+
max_duration_in_seconds: float = field(
|
196 |
+
default=20.0,
|
197 |
+
metadata={
|
198 |
+
"help": "Filter audio files that are longer than `max_duration_in_seconds` seconds to 'max_duration_in_seconds`"
|
199 |
+
},
|
200 |
+
)
|
201 |
+
min_duration_in_seconds: float = field(
|
202 |
+
default=0.0, metadata={"help": "Filter audio files that are shorter than `min_duration_in_seconds` seconds"}
|
203 |
+
)
|
204 |
+
preprocessing_only: bool = field(
|
205 |
+
default=False,
|
206 |
+
metadata={
|
207 |
+
"help": "Whether to only do data preprocessing and skip training. "
|
208 |
+
"This is especially useful when data preprocessing errors out in distributed training due to timeout. "
|
209 |
+
"In this case, one should run the preprocessing in a non-distributed setup with `preprocessing_only=True` "
|
210 |
+
"so that the cached datasets can consequently be loaded in distributed training"
|
211 |
+
},
|
212 |
+
)
|
213 |
+
use_auth_token: bool = field(
|
214 |
+
default=False,
|
215 |
+
metadata={
|
216 |
+
"help": "If :obj:`True`, will use the token generated when running"
|
217 |
+
":obj:`transformers-cli login` as HTTP bearer authorization for remote files."
|
218 |
+
},
|
219 |
+
)
|
220 |
+
unk_token: str = field(
|
221 |
+
default="[UNK]",
|
222 |
+
metadata={"help": "The unk token for the tokenizer"},
|
223 |
+
)
|
224 |
+
pad_token: str = field(
|
225 |
+
default="[PAD]",
|
226 |
+
metadata={"help": "The padding token for the tokenizer"},
|
227 |
+
)
|
228 |
+
word_delimiter_token: str = field(
|
229 |
+
default="|",
|
230 |
+
metadata={"help": "The word delimiter token for the tokenizer"},
|
231 |
+
)
|
232 |
+
phoneme_language: Optional[str] = field(
|
233 |
+
default=None,
|
234 |
+
metadata={
|
235 |
+
"help": "The target language that should be used be"
|
236 |
+
" passed to the tokenizer for tokenization. Note that"
|
237 |
+
" this is only relevant if the model classifies the"
|
238 |
+
" input audio to a sequence of phoneme sequences."
|
239 |
+
},
|
240 |
+
)
|
241 |
+
|
242 |
+
|
243 |
+
@dataclass
|
244 |
+
class DataCollatorCTCWithPadding:
|
245 |
+
"""
|
246 |
+
Data collator that will dynamically pad the inputs received.
|
247 |
+
Args:
|
248 |
+
processor (:class:`~transformers.AutoProcessor`)
|
249 |
+
The processor used for proccessing the data.
|
250 |
+
padding (:obj:`bool`, :obj:`str` or :class:`~transformers.tokenization_utils_base.PaddingStrategy`, `optional`, defaults to :obj:`True`):
|
251 |
+
Select a strategy to pad the returned sequences (according to the model's padding side and padding index)
|
252 |
+
among:
|
253 |
+
* :obj:`True` or :obj:`'longest'`: Pad to the longest sequence in the batch (or no padding if only a single
|
254 |
+
sequence if provided).
|
255 |
+
* :obj:`'max_length'`: Pad to a maximum length specified with the argument :obj:`max_length` or to the
|
256 |
+
maximum acceptable input length for the model if that argument is not provided.
|
257 |
+
* :obj:`False` or :obj:`'do_not_pad'` (default): No padding (i.e., can output a batch with sequences of
|
258 |
+
different lengths).
|
259 |
+
max_length (:obj:`int`, `optional`):
|
260 |
+
Maximum length of the ``input_values`` of the returned list and optionally padding length (see above).
|
261 |
+
max_length_labels (:obj:`int`, `optional`):
|
262 |
+
Maximum length of the ``labels`` returned list and optionally padding length (see above).
|
263 |
+
pad_to_multiple_of (:obj:`int`, `optional`):
|
264 |
+
If set will pad the sequence to a multiple of the provided value.
|
265 |
+
This is especially useful to enable the use of Tensor Cores on NVIDIA hardware with compute capability >=
|
266 |
+
7.5 (Volta).
|
267 |
+
"""
|
268 |
+
|
269 |
+
processor: AutoProcessor
|
270 |
+
padding: Union[bool, str] = "longest"
|
271 |
+
pad_to_multiple_of: Optional[int] = None
|
272 |
+
pad_to_multiple_of_labels: Optional[int] = None
|
273 |
+
|
274 |
+
def __call__(self, features: List[Dict[str, Union[List[int], torch.Tensor]]]) -> Dict[str, torch.Tensor]:
|
275 |
+
# split inputs and labels since they have to be of different lenghts and need
|
276 |
+
# different padding methods
|
277 |
+
input_features = [{"input_values": feature["input_values"]} for feature in features]
|
278 |
+
label_features = [{"input_ids": feature["labels"]} for feature in features]
|
279 |
+
|
280 |
+
batch = self.processor.pad(
|
281 |
+
input_features,
|
282 |
+
padding=self.padding,
|
283 |
+
pad_to_multiple_of=self.pad_to_multiple_of,
|
284 |
+
return_tensors="pt",
|
285 |
+
)
|
286 |
+
|
287 |
+
with self.processor.as_target_processor():
|
288 |
+
labels_batch = self.processor.pad(
|
289 |
+
label_features,
|
290 |
+
padding=self.padding,
|
291 |
+
pad_to_multiple_of=self.pad_to_multiple_of_labels,
|
292 |
+
return_tensors="pt",
|
293 |
+
)
|
294 |
+
|
295 |
+
# replace padding with -100 to ignore loss correctly
|
296 |
+
labels = labels_batch["input_ids"].masked_fill(labels_batch.attention_mask.ne(1), -100)
|
297 |
+
|
298 |
+
batch["labels"] = labels
|
299 |
+
|
300 |
+
return batch
|
301 |
+
|
302 |
+
|
303 |
+
def create_vocabulary_from_data(
|
304 |
+
datasets: DatasetDict,
|
305 |
+
word_delimiter_token: Optional[str] = None,
|
306 |
+
unk_token: Optional[str] = None,
|
307 |
+
pad_token: Optional[str] = None,
|
308 |
+
):
|
309 |
+
# Given training and test labels create vocabulary
|
310 |
+
def extract_all_chars(batch):
|
311 |
+
all_text = " ".join(batch["target_text"])
|
312 |
+
vocab = list(set(all_text))
|
313 |
+
return {"vocab": [vocab], "all_text": [all_text]}
|
314 |
+
|
315 |
+
vocabs = datasets.map(
|
316 |
+
extract_all_chars,
|
317 |
+
batched=True,
|
318 |
+
batch_size=-1,
|
319 |
+
keep_in_memory=True,
|
320 |
+
remove_columns=datasets["train"].column_names,
|
321 |
+
)
|
322 |
+
|
323 |
+
# take union of all unique characters in each dataset
|
324 |
+
vocab_set = functools.reduce(
|
325 |
+
lambda vocab_1, vocab_2: set(vocab_1["vocab"][0]) | set(vocab_2["vocab"][0]), vocabs.values()
|
326 |
+
)
|
327 |
+
|
328 |
+
vocab_dict = {v: k for k, v in enumerate(sorted(list(vocab_set)))}
|
329 |
+
|
330 |
+
# replace white space with delimiter token
|
331 |
+
if word_delimiter_token is not None:
|
332 |
+
vocab_dict[word_delimiter_token] = vocab_dict[" "]
|
333 |
+
del vocab_dict[" "]
|
334 |
+
|
335 |
+
# add unk and pad token
|
336 |
+
if unk_token is not None:
|
337 |
+
vocab_dict[unk_token] = len(vocab_dict)
|
338 |
+
|
339 |
+
if pad_token is not None:
|
340 |
+
vocab_dict[pad_token] = len(vocab_dict)
|
341 |
+
|
342 |
+
return vocab_dict
|
343 |
+
|
344 |
+
|
345 |
+
def main():
|
346 |
+
# See all possible arguments in src/transformers/training_args.py
|
347 |
+
# or by passing the --help flag to this script.
|
348 |
+
# We now keep distinct sets of args, for a cleaner separation of concerns.
|
349 |
+
|
350 |
+
parser = HfArgumentParser((ModelArguments, DataTrainingArguments, TrainingArguments))
|
351 |
+
if len(sys.argv) == 2 and sys.argv[1].endswith(".json"):
|
352 |
+
# If we pass only one argument to the script and it's the path to a json file,
|
353 |
+
# let's parse it to get our arguments.
|
354 |
+
model_args, data_args, training_args = parser.parse_json_file(json_file=os.path.abspath(sys.argv[1]))
|
355 |
+
else:
|
356 |
+
model_args, data_args, training_args = parser.parse_args_into_dataclasses()
|
357 |
+
|
358 |
+
# Detecting last checkpoint.
|
359 |
+
last_checkpoint = None
|
360 |
+
if os.path.isdir(training_args.output_dir) and training_args.do_train and not training_args.overwrite_output_dir:
|
361 |
+
last_checkpoint = get_last_checkpoint(training_args.output_dir)
|
362 |
+
if last_checkpoint is None and len(os.listdir(training_args.output_dir)) > 0:
|
363 |
+
raise ValueError(
|
364 |
+
f"Output directory ({training_args.output_dir}) already exists and is not empty. "
|
365 |
+
"Use --overwrite_output_dir to overcome."
|
366 |
+
)
|
367 |
+
elif last_checkpoint is not None:
|
368 |
+
logger.info(
|
369 |
+
f"Checkpoint detected, resuming training at {last_checkpoint}. To avoid this behavior, change "
|
370 |
+
"the `--output_dir` or add `--overwrite_output_dir` to train from scratch."
|
371 |
+
)
|
372 |
+
|
373 |
+
# Setup logging
|
374 |
+
logging.basicConfig(
|
375 |
+
format="%(asctime)s - %(levelname)s - %(name)s - %(message)s",
|
376 |
+
datefmt="%m/%d/%Y %H:%M:%S",
|
377 |
+
handlers=[logging.StreamHandler(sys.stdout)],
|
378 |
+
)
|
379 |
+
logger.setLevel(logging.INFO if is_main_process(training_args.local_rank) else logging.WARN)
|
380 |
+
|
381 |
+
# Log on each process the small summary:
|
382 |
+
logger.warning(
|
383 |
+
f"Process rank: {training_args.local_rank}, device: {training_args.device}, n_gpu: {training_args.n_gpu}"
|
384 |
+
f"distributed training: {bool(training_args.local_rank != -1)}, 16-bits training: {training_args.fp16}"
|
385 |
+
)
|
386 |
+
# Set the verbosity to info of the Transformers logger (on main process only):
|
387 |
+
if is_main_process(training_args.local_rank):
|
388 |
+
transformers.utils.logging.set_verbosity_info()
|
389 |
+
logger.info("Training/evaluation parameters %s", training_args)
|
390 |
+
|
391 |
+
# Set seed before initializing model.
|
392 |
+
set_seed(training_args.seed)
|
393 |
+
|
394 |
+
# 1. First, let's load the dataset
|
395 |
+
raw_datasets = DatasetDict()
|
396 |
+
|
397 |
+
if training_args.do_train:
|
398 |
+
raw_datasets["train"] = load_dataset(
|
399 |
+
data_args.dataset_name,
|
400 |
+
data_args.dataset_config_name,
|
401 |
+
split=data_args.train_split_name,
|
402 |
+
use_auth_token=data_args.use_auth_token,
|
403 |
+
)
|
404 |
+
|
405 |
+
if data_args.audio_column_name not in raw_datasets["train"].column_names:
|
406 |
+
raise ValueError(
|
407 |
+
f"--audio_column_name '{data_args.audio_column_name}' not found in dataset '{data_args.dataset_name}'. "
|
408 |
+
"Make sure to set `--audio_column_name` to the correct audio column - one of "
|
409 |
+
f"{', '.join(raw_datasets['train'].column_names)}."
|
410 |
+
)
|
411 |
+
|
412 |
+
if data_args.text_column_name not in raw_datasets["train"].column_names:
|
413 |
+
raise ValueError(
|
414 |
+
f"--text_column_name {data_args.text_column_name} not found in dataset '{data_args.dataset_name}'. "
|
415 |
+
"Make sure to set `--text_column_name` to the correct text column - one of "
|
416 |
+
f"{', '.join(raw_datasets['train'].column_names)}."
|
417 |
+
)
|
418 |
+
|
419 |
+
if data_args.max_train_samples is not None:
|
420 |
+
raw_datasets["train"] = raw_datasets["train"].select(range(data_args.max_train_samples))
|
421 |
+
|
422 |
+
if training_args.do_eval:
|
423 |
+
raw_datasets["eval"] = load_dataset(
|
424 |
+
data_args.dataset_name,
|
425 |
+
data_args.dataset_config_name,
|
426 |
+
split=data_args.eval_split_name,
|
427 |
+
use_auth_token=data_args.use_auth_token,
|
428 |
+
)
|
429 |
+
|
430 |
+
if data_args.max_eval_samples is not None:
|
431 |
+
raw_datasets["eval"] = raw_datasets["eval"].select(range(data_args.max_eval_samples))
|
432 |
+
|
433 |
+
# 2. We remove some special characters from the datasets
|
434 |
+
# that make training complicated and do not help in transcribing the speech
|
435 |
+
# E.g. characters, such as `,` and `.` do not really have an acoustic characteristic
|
436 |
+
# that could be easily picked up by the model
|
437 |
+
chars_to_ignore_regex = (
|
438 |
+
f'[{"".join(data_args.chars_to_ignore)}]' if data_args.chars_to_ignore is not None else None
|
439 |
+
)
|
440 |
+
text_column_name = data_args.text_column_name
|
441 |
+
|
442 |
+
def remove_special_characters(batch):
|
443 |
+
if chars_to_ignore_regex is not None:
|
444 |
+
batch["target_text"] = re.sub(chars_to_ignore_regex, "", batch[text_column_name]).lower() + " "
|
445 |
+
else:
|
446 |
+
batch["target_text"] = batch[text_column_name].lower() + " "
|
447 |
+
return batch
|
448 |
+
|
449 |
+
with training_args.main_process_first(desc="dataset map special characters removal"):
|
450 |
+
raw_datasets = raw_datasets.map(
|
451 |
+
remove_special_characters,
|
452 |
+
remove_columns=[text_column_name],
|
453 |
+
desc="remove special characters from datasets",
|
454 |
+
)
|
455 |
+
|
456 |
+
# save special tokens for tokenizer
|
457 |
+
word_delimiter_token = data_args.word_delimiter_token
|
458 |
+
unk_token = data_args.unk_token
|
459 |
+
pad_token = data_args.pad_token
|
460 |
+
|
461 |
+
# 3. Next, let's load the config as we might need it to create
|
462 |
+
# the tokenizer
|
463 |
+
# load config
|
464 |
+
config = AutoConfig.from_pretrained(
|
465 |
+
model_args.model_name_or_path, cache_dir=model_args.cache_dir, use_auth_token=data_args.use_auth_token
|
466 |
+
)
|
467 |
+
|
468 |
+
# 4. Next, if no tokenizer file is defined,
|
469 |
+
# we create the vocabulary of the model by extracting all unique characters from
|
470 |
+
# the training and evaluation datasets
|
471 |
+
# We need to make sure that only first rank saves vocabulary
|
472 |
+
# make sure all processes wait until vocab is created
|
473 |
+
tokenizer_name_or_path = model_args.tokenizer_name_or_path
|
474 |
+
tokenizer_kwargs = {}
|
475 |
+
if tokenizer_name_or_path is None:
|
476 |
+
# save vocab in training output dir
|
477 |
+
tokenizer_name_or_path = training_args.output_dir
|
478 |
+
|
479 |
+
vocab_file = os.path.join(tokenizer_name_or_path, "vocab.json")
|
480 |
+
|
481 |
+
with training_args.main_process_first():
|
482 |
+
if training_args.overwrite_output_dir and os.path.isfile(vocab_file):
|
483 |
+
os.remove(vocab_file)
|
484 |
+
|
485 |
+
with training_args.main_process_first(desc="dataset map vocabulary creation"):
|
486 |
+
if not os.path.isfile(vocab_file):
|
487 |
+
os.makedirs(tokenizer_name_or_path, exist_ok=True)
|
488 |
+
vocab_dict = create_vocabulary_from_data(
|
489 |
+
raw_datasets,
|
490 |
+
word_delimiter_token=word_delimiter_token,
|
491 |
+
unk_token=unk_token,
|
492 |
+
pad_token=pad_token,
|
493 |
+
)
|
494 |
+
|
495 |
+
# save vocab dict to be loaded into tokenizer
|
496 |
+
with open(vocab_file, "w") as file:
|
497 |
+
json.dump(vocab_dict, file)
|
498 |
+
|
499 |
+
# if tokenizer has just been created
|
500 |
+
# it is defined by `tokenizer_class` if present in config else by `model_type`
|
501 |
+
tokenizer_kwargs = {
|
502 |
+
"config": config if config.tokenizer_class is not None else None,
|
503 |
+
"tokenizer_type": config.model_type if config.tokenizer_class is None else None,
|
504 |
+
"unk_token": unk_token,
|
505 |
+
"pad_token": pad_token,
|
506 |
+
"word_delimiter_token": word_delimiter_token,
|
507 |
+
}
|
508 |
+
|
509 |
+
# 5. Now we can instantiate the feature extractor, tokenizer and model
|
510 |
+
# Note for distributed training, the .from_pretrained methods guarantee that only
|
511 |
+
# one local process can concurrently download model & vocab.
|
512 |
+
|
513 |
+
# load feature_extractor and tokenizer
|
514 |
+
tokenizer = AutoTokenizer.from_pretrained(
|
515 |
+
tokenizer_name_or_path,
|
516 |
+
use_auth_token=data_args.use_auth_token,
|
517 |
+
**tokenizer_kwargs,
|
518 |
+
)
|
519 |
+
feature_extractor = AutoFeatureExtractor.from_pretrained(
|
520 |
+
model_args.model_name_or_path, cache_dir=model_args.cache_dir, use_auth_token=data_args.use_auth_token
|
521 |
+
)
|
522 |
+
|
523 |
+
# adapt config
|
524 |
+
config.update(
|
525 |
+
{
|
526 |
+
"feat_proj_dropout": model_args.feat_proj_dropout,
|
527 |
+
"attention_dropout": model_args.attention_dropout,
|
528 |
+
"hidden_dropout": model_args.hidden_dropout,
|
529 |
+
"final_dropout": model_args.final_dropout,
|
530 |
+
"mask_time_prob": model_args.mask_time_prob,
|
531 |
+
"mask_time_length": model_args.mask_time_length,
|
532 |
+
"mask_feature_prob": model_args.mask_feature_prob,
|
533 |
+
"mask_feature_length": model_args.mask_feature_length,
|
534 |
+
"gradient_checkpointing": training_args.gradient_checkpointing,
|
535 |
+
"layerdrop": model_args.layerdrop,
|
536 |
+
"ctc_loss_reduction": model_args.ctc_loss_reduction,
|
537 |
+
"pad_token_id": tokenizer.pad_token_id,
|
538 |
+
"vocab_size": len(tokenizer),
|
539 |
+
"activation_dropout": model_args.activation_dropout,
|
540 |
+
}
|
541 |
+
)
|
542 |
+
|
543 |
+
# create model
|
544 |
+
model = AutoModelForCTC.from_pretrained(
|
545 |
+
model_args.model_name_or_path,
|
546 |
+
cache_dir=model_args.cache_dir,
|
547 |
+
config=config,
|
548 |
+
use_auth_token=data_args.use_auth_token,
|
549 |
+
)
|
550 |
+
|
551 |
+
# freeze encoder
|
552 |
+
if model_args.freeze_feature_encoder:
|
553 |
+
model.freeze_feature_encoder()
|
554 |
+
|
555 |
+
# 6. Now we preprocess the datasets including loading the audio, resampling and normalization
|
556 |
+
# Thankfully, `datasets` takes care of automatically loading and resampling the audio,
|
557 |
+
# so that we just need to set the correct target sampling rate and normalize the input
|
558 |
+
# via the `feature_extractor`
|
559 |
+
|
560 |
+
# make sure that dataset decodes audio with correct sampling rate
|
561 |
+
dataset_sampling_rate = next(iter(raw_datasets.values())).features[data_args.audio_column_name].sampling_rate
|
562 |
+
if dataset_sampling_rate != feature_extractor.sampling_rate:
|
563 |
+
raw_datasets = raw_datasets.cast_column(
|
564 |
+
data_args.audio_column_name, datasets.features.Audio(sampling_rate=feature_extractor.sampling_rate)
|
565 |
+
)
|
566 |
+
|
567 |
+
# derive max & min input length for sample rate & max duration
|
568 |
+
max_input_length = data_args.max_duration_in_seconds * feature_extractor.sampling_rate
|
569 |
+
min_input_length = data_args.min_duration_in_seconds * feature_extractor.sampling_rate
|
570 |
+
audio_column_name = data_args.audio_column_name
|
571 |
+
num_workers = data_args.preprocessing_num_workers
|
572 |
+
|
573 |
+
# `phoneme_language` is only relevant if the model is fine-tuned on phoneme classification
|
574 |
+
phoneme_language = data_args.phoneme_language
|
575 |
+
|
576 |
+
# Preprocessing the datasets.
|
577 |
+
# We need to read the audio files as arrays and tokenize the targets.
|
578 |
+
def prepare_dataset(batch):
|
579 |
+
# load audio
|
580 |
+
sample = batch[audio_column_name]
|
581 |
+
|
582 |
+
inputs = feature_extractor(sample["array"], sampling_rate=sample["sampling_rate"])
|
583 |
+
batch["input_values"] = inputs.input_values[0]
|
584 |
+
batch["input_length"] = len(batch["input_values"])
|
585 |
+
|
586 |
+
# encode targets
|
587 |
+
additional_kwargs = {}
|
588 |
+
if phoneme_language is not None:
|
589 |
+
additional_kwargs["phonemizer_lang"] = phoneme_language
|
590 |
+
|
591 |
+
batch["labels"] = tokenizer(batch["target_text"], **additional_kwargs).input_ids
|
592 |
+
return batch
|
593 |
+
|
594 |
+
with training_args.main_process_first(desc="dataset map preprocessing"):
|
595 |
+
vectorized_datasets = raw_datasets.map(
|
596 |
+
prepare_dataset,
|
597 |
+
remove_columns=next(iter(raw_datasets.values())).column_names,
|
598 |
+
num_proc=num_workers,
|
599 |
+
desc="preprocess datasets",
|
600 |
+
)
|
601 |
+
|
602 |
+
def is_audio_in_length_range(length):
|
603 |
+
return length > min_input_length and length < max_input_length
|
604 |
+
|
605 |
+
# filter data that is shorter than min_input_length
|
606 |
+
vectorized_datasets = vectorized_datasets.filter(
|
607 |
+
is_audio_in_length_range,
|
608 |
+
num_proc=num_workers,
|
609 |
+
input_columns=["input_length"],
|
610 |
+
)
|
611 |
+
|
612 |
+
# 7. Next, we can prepare the training.
|
613 |
+
# Let's use word error rate (WER) as our evaluation metric,
|
614 |
+
# instantiate a data collator and the trainer
|
615 |
+
|
616 |
+
# Define evaluation metrics during training, *i.e.* word error rate, character error rate
|
617 |
+
eval_metrics = {metric: load_metric(metric) for metric in data_args.eval_metrics}
|
618 |
+
|
619 |
+
# for large datasets it is advised to run the preprocessing on a
|
620 |
+
# single machine first with ``args.preprocessing_only`` since there will mostly likely
|
621 |
+
# be a timeout when running the script in distributed mode.
|
622 |
+
# In a second step ``args.preprocessing_only`` can then be set to `False` to load the
|
623 |
+
# cached dataset
|
624 |
+
if data_args.preprocessing_only:
|
625 |
+
logger.info(f"Data preprocessing finished. Files cached at {vectorized_datasets.cache_files}")
|
626 |
+
return
|
627 |
+
|
628 |
+
def compute_metrics(pred):
|
629 |
+
pred_logits = pred.predictions
|
630 |
+
pred_ids = np.argmax(pred_logits, axis=-1)
|
631 |
+
|
632 |
+
pred.label_ids[pred.label_ids == -100] = tokenizer.pad_token_id
|
633 |
+
|
634 |
+
pred_str = tokenizer.batch_decode(pred_ids)
|
635 |
+
# we do not want to group tokens when computing the metrics
|
636 |
+
label_str = tokenizer.batch_decode(pred.label_ids, group_tokens=False)
|
637 |
+
|
638 |
+
metrics = {k: v.compute(predictions=pred_str, references=label_str) for k, v in eval_metrics.items()}
|
639 |
+
|
640 |
+
return metrics
|
641 |
+
|
642 |
+
# Now save everything to be able to create a single processor later
|
643 |
+
if is_main_process(training_args.local_rank):
|
644 |
+
# save feature extractor, tokenizer and config
|
645 |
+
feature_extractor.save_pretrained(training_args.output_dir)
|
646 |
+
tokenizer.save_pretrained(training_args.output_dir)
|
647 |
+
config.save_pretrained(training_args.output_dir)
|
648 |
+
|
649 |
+
try:
|
650 |
+
processor = AutoProcessor.from_pretrained(training_args.output_dir)
|
651 |
+
except (OSError, KeyError):
|
652 |
+
warnings.warn(
|
653 |
+
"Loading a processor from a feature extractor config that does not"
|
654 |
+
" include a `processor_class` attribute is deprecated and will be removed in v5. Please add the following "
|
655 |
+
" attribute to your `preprocessor_config.json` file to suppress this warning: "
|
656 |
+
" `'processor_class': 'Wav2Vec2Processor'`",
|
657 |
+
FutureWarning,
|
658 |
+
)
|
659 |
+
processor = Wav2Vec2Processor.from_pretrained(training_args.output_dir)
|
660 |
+
|
661 |
+
# Instantiate custom data collator
|
662 |
+
data_collator = DataCollatorCTCWithPadding(processor=processor)
|
663 |
+
|
664 |
+
# Initialize Trainer
|
665 |
+
trainer = Trainer(
|
666 |
+
model=model,
|
667 |
+
data_collator=data_collator,
|
668 |
+
args=training_args,
|
669 |
+
compute_metrics=compute_metrics,
|
670 |
+
train_dataset=vectorized_datasets["train"] if training_args.do_train else None,
|
671 |
+
eval_dataset=vectorized_datasets["eval"] if training_args.do_eval else None,
|
672 |
+
tokenizer=feature_extractor,
|
673 |
+
)
|
674 |
+
|
675 |
+
# 8. Finally, we can start training
|
676 |
+
|
677 |
+
# Training
|
678 |
+
if training_args.do_train:
|
679 |
+
|
680 |
+
# use last checkpoint if exist
|
681 |
+
if last_checkpoint is not None:
|
682 |
+
checkpoint = last_checkpoint
|
683 |
+
elif os.path.isdir(model_args.model_name_or_path):
|
684 |
+
checkpoint = model_args.model_name_or_path
|
685 |
+
else:
|
686 |
+
checkpoint = None
|
687 |
+
|
688 |
+
train_result = trainer.train(resume_from_checkpoint=checkpoint)
|
689 |
+
trainer.save_model()
|
690 |
+
|
691 |
+
metrics = train_result.metrics
|
692 |
+
max_train_samples = (
|
693 |
+
data_args.max_train_samples
|
694 |
+
if data_args.max_train_samples is not None
|
695 |
+
else len(vectorized_datasets["train"])
|
696 |
+
)
|
697 |
+
metrics["train_samples"] = min(max_train_samples, len(vectorized_datasets["train"]))
|
698 |
+
|
699 |
+
trainer.log_metrics("train", metrics)
|
700 |
+
trainer.save_metrics("train", metrics)
|
701 |
+
trainer.save_state()
|
702 |
+
|
703 |
+
# Evaluation
|
704 |
+
results = {}
|
705 |
+
if training_args.do_eval:
|
706 |
+
logger.info("*** Evaluate ***")
|
707 |
+
metrics = trainer.evaluate()
|
708 |
+
max_eval_samples = (
|
709 |
+
data_args.max_eval_samples if data_args.max_eval_samples is not None else len(vectorized_datasets["eval"])
|
710 |
+
)
|
711 |
+
metrics["eval_samples"] = min(max_eval_samples, len(vectorized_datasets["eval"]))
|
712 |
+
|
713 |
+
trainer.log_metrics("eval", metrics)
|
714 |
+
trainer.save_metrics("eval", metrics)
|
715 |
+
|
716 |
+
# Write model card and (optionally) push to hub
|
717 |
+
config_name = data_args.dataset_config_name if data_args.dataset_config_name is not None else "na"
|
718 |
+
kwargs = {
|
719 |
+
"finetuned_from": model_args.model_name_or_path,
|
720 |
+
"tasks": "speech-recognition",
|
721 |
+
"tags": ["automatic-speech-recognition", data_args.dataset_name],
|
722 |
+
"dataset_args": f"Config: {config_name}, Training split: {data_args.train_split_name}, Eval split: {data_args.eval_split_name}",
|
723 |
+
"dataset": f"{data_args.dataset_name.upper()} - {config_name.upper()}",
|
724 |
+
}
|
725 |
+
if "common_voice" in data_args.dataset_name:
|
726 |
+
kwargs["language"] = config_name
|
727 |
+
|
728 |
+
if training_args.push_to_hub:
|
729 |
+
trainer.push_to_hub(**kwargs)
|
730 |
+
else:
|
731 |
+
trainer.create_model_card(**kwargs)
|
732 |
+
|
733 |
+
return results
|
734 |
+
|
735 |
+
|
736 |
+
if __name__ == "__main__":
|
737 |
+
main()
|
runs/Feb06_11-36-42_job-a1cf84c8-7d28-46cd-9f0a-e09d16d4a1cb/1644147756.2090228/events.out.tfevents.1644147756.job-a1cf84c8-7d28-46cd-9f0a-e09d16d4a1cb
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:24fc4152329db3b74b1338a8b50a320797175adce3a81e200f96a07bda06b171
|
3 |
+
size 4564
|
runs/Feb06_11-36-42_job-a1cf84c8-7d28-46cd-9f0a-e09d16d4a1cb/events.out.tfevents.1644147756.job-a1cf84c8-7d28-46cd-9f0a-e09d16d4a1cb
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:821b363f9f0c7e01e262140f86ea15533973931df050927787bf6cd8a58966ae
|
3 |
+
size 5469
|
special_tokens_map.json
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
{"bos_token": "<s>", "eos_token": "</s>", "unk_token": "[UNK]", "pad_token": "[PAD]", "additional_special_tokens": [{"content": "<s>", "single_word": false, "lstrip": false, "rstrip": false, "normalized": true}, {"content": "</s>", "single_word": false, "lstrip": false, "rstrip": false, "normalized": true}]}
|
tokenizer_config.json
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
{"unk_token": "[UNK]", "bos_token": "<s>", "eos_token": "</s>", "pad_token": "[PAD]", "do_lower_case": false, "word_delimiter_token": "|", "special_tokens_map_file": null, "tokenizer_file": null, "name_or_path": "./", "tokenizer_class": "Wav2Vec2CTCTokenizer"}
|
training_args.bin
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:4a469c981d4d62468b48b0c073767de94a5f1647e0331c141c520301d4be0e48
|
3 |
+
size 2991
|
vocab.json
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
{"d": 1, "g": 2, "i": 3, "l": 4, "p": 5, "q": 6, "ㄟ": 7, "一": 8, "丁": 9, "七": 10, "丈": 11, "三": 12, "上": 13, "下": 14, "不": 15, "且": 16, "世": 17, "丘": 18, "丙": 19, "丟": 20, "並": 21, "中": 22, "串": 23, "丶": 24, "丹": 25, "主": 26, "乃": 27, "久": 28, "之": 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, "令": 69, "以": 70, "仰": 71, "仲": 72, "件": 73, "任": 74, "份": 75, "仿": 76, "企": 77, "伊": 78, "伏": 79, "伐": 80, "休": 81, "伯": 82, "估": 83, "伴": 84, "伸": 85, "伺": 86, "似": 87, "佃": 88, "但": 89, "佈": 90, "位": 91, "低": 92, "住": 93, "佑": 94, "佔": 95, "何": 96, "作": 97, "你": 98, "佳": 99, "併": 100, "使": 101, "來": 102, "侈": 103, "例": 104, "供": 105, "依": 106, "侮": 107, "侯": 108, "侵": 109, "侶": 110, "便": 111, "係": 112, "促": 113, "俄": 114, "俊": 115, "俗": 116, "保": 117, "信": 118, "修": 119, "俱": 120, "倉": 121, "個": 122, "倍": 123, "們": 124, "倒": 125, "候": 126, "倚": 127, "借": 128, "倡": 129, "値": 130, "倦": 131, "倫": 132, "值": 133, "假": 134, "偉": 135, "偏": 136, "做": 137, "停": 138, "健": 139, "側": 140, "偵": 141, "偶": 142, "偷": 143, "傅": 144, "傍": 145, "傑": 146, "傘": 147, "備": 148, "催": 149, "傲": 150, "傳": 151, "債": 152, "傷": 153, "傻": 154, "傾": 155, "僅": 156, "像": 157, "僚": 158, "僱": 159, "僵": 160, "價": 161, "儀": 162, "億": 163, "儘": 164, "償": 165, "優": 166, "儲": 167, "兀": 168, "允": 169, "元": 170, "兄": 171, "充": 172, "兇": 173, "先": 174, "光": 175, "克": 176, "免": 177, "兒": 178, "入": 179, "內": 180, "全": 181, "兩": 182, "八": 183, "公": 184, "六": 185, "兮": 186, "共": 187, "兵": 188, "其": 189, "具": 190, "典": 191, "兼": 192, "内": 193, "冊": 194, "再": 195, "冒": 196, "冗": 197, "冠": 198, "冤": 199, "冬": 200, "冰": 201, "冷": 202, "准": 203, "凋": 204, "凌": 205, "凍": 206, "凝": 207, "凡": 208, "凱": 209, "凹": 210, "出": 211, "函": 212, "刀": 213, "刁": 214, "分": 215, "切": 216, "刊": 217, "刑": 218, "划": 219, "列": 220, "初": 221, "判": 222, "別": 223, "利": 224, "刪": 225, "到": 226, "制": 227, "刷": 228, "券": 229, "刺": 230, "刻": 231, "則": 232, "前": 233, "剖": 234, "剛": 235, "剝": 236, "剩": 237, "剪": 238, "副": 239, "割": 240, "創": 241, "劃": 242, "劇": 243, "劈": 244, "劉": 245, "劍": 246, "劑": 247, "力": 248, "功": 249, "加": 250, "劣": 251, "助": 252, "努": 253, "勁": 254, "勇": 255, "勉": 256, "動": 257, "勘": 258, "務": 259, "勝": 260, "勞": 261, "募": 262, "勢": 263, "勤": 264, "勳": 265, "勵": 266, "勸": 267, "勾": 268, "勿": 269, "包": 270, "化": 271, "北": 272, "匙": 273, "匯": 274, "匱": 275, "區": 276, "十": 277, "千": 278, "升": 279, "午": 280, "半": 281, "卑": 282, "卓": 283, "協": 284, "南": 285, "博": 286, "占": 287, "卡": 288, "卦": 289, "印": 290, "危": 291, "即": 292, "卵": 293, "卷": 294, "卸": 295, "卻": 296, "厄": 297, "厚": 298, "原": 299, "厭": 300, "厲": 301, "去": 302, "參": 303, "又": 304, "叉": 305, "及": 306, "友": 307, "反": 308, "叔": 309, "取": 310, "受": 311, "叛": 312, "叢": 313, "口": 314, "古": 315, "句": 316, "另": 317, "叨": 318, "只": 319, "叫": 320, "召": 321, "叮": 322, "可": 323, "台": 324, "史": 325, "右": 326, "司": 327, "吃": 328, "各": 329, "合": 330, "吉": 331, "吊": 332, "同": 333, "名": 334, "吐": 335, "向": 336, "君": 337, "否": 338, "吧": 339, "含": 340, "吭": 341, "吸": 342, "吹": 343, "吻": 344, "吼": 345, "呀": 346, "呂": 347, "呆": 348, "呈": 349, "告": 350, "呢": 351, "周": 352, "呱": 353, "味": 354, "呵": 355, "呼": 356, "命": 357, "咆": 358, "和": 359, "咕": 360, "咖": 361, "咬": 362, "咳": 363, "哀": 364, "品": 365, "哄": 366, "哇": 367, "哈": 368, "哉": 369, "哎": 370, "員": 371, "哥": 372, "哦": 373, "哩": 374, "哪": 375, "哭": 376, "哲": 377, "哺": 378, "哼": 379, "唆": 380, "唐": 381, "唬": 382, "售": 383, "唯": 384, "唱": 385, "唷": 386, "唸": 387, "商": 388, "啊": 389, "問": 390, "啖": 391, "啟": 392, "啡": 393, "啤": 394, "啥": 395, "啦": 396, "啼": 397, "善": 398, "喉": 399, "喊": 400, "喔": 401, "喘": 402, "喜": 403, "喝": 404, "喧": 405, "喪": 406, "喬": 407, "單": 408, "喵": 409, "喻": 410, "嗆": 411, "嗎": 412, "嗚": 413, "嗜": 414, "嗨": 415, "嗯": 416, "嗽": 417, "嘆": 418, "嘉": 419, "嘍": 420, "嘗": 421, "嘛": 422, "嘯": 423, "嘰": 424, "嘲": 425, "嘴": 426, "嘻": 427, "噌": 428, "噓": 429, "噗": 430, "器": 431, "噴": 432, "噶": 433, "噸": 434, "噹": 435, "嚀": 436, "嚇": 437, "嚕": 438, "嚨": 439, "嚴": 440, "嚼": 441, "囉": 442, "四": 443, "回": 444, "因": 445, "困": 446, "固": 447, "圈": 448, "國": 449, "圍": 450, "園": 451, "圓": 452, "圖": 453, "團": 454, "土": 455, "在": 456, "地": 457, "圾": 458, "址": 459, "均": 460, "坊": 461, "坐": 462, "坑": 463, "坡": 464, "坦": 465, "坪": 466, "垂": 467, "垃": 468, "型": 469, "埋": 470, "城": 471, "域": 472, "執": 473, "培": 474, "基": 475, "堂": 476, "堅": 477, "堆": 478, "堡": 479, "堪": 480, "報": 481, "場": 482, "堵": 483, "塊": 484, "塑": 485, "塔": 486, "塗": 487, "塞": 488, "填": 489, "塭": 490, "境": 491, "墓": 492, "增": 493, "墨": 494, "墮": 495, "墾": 496, "壁": 497, "壇": 498, "壓": 499, "壘": 500, "壞": 501, "壟": 502, "士": 503, "壯": 504, "壺": 505, "壽": 506, "夏": 507, "夕": 508, "外": 509, "多": 510, "夜": 511, "夠": 512, "夢": 513, "夥": 514, "大": 515, "天": 516, "太": 517, "夫": 518, "央": 519, "失": 520, "夷": 521, "夾": 522, "奇": 523, "奈": 524, "奉": 525, "奏": 526, "契": 527, "奔": 528, "套": 529, "奢": 530, "奧": 531, "奪": 532, "奮": 533, "女": 534, "奶": 535, "奸": 536, "她": 537, "好": 538, "如": 539, "妃": 540, "妄": 541, "妖": 542, "妙": 543, "妥": 544, "妨": 545, "妳": 546, "妹": 547, "妻": 548, "妾": 549, "姆": 550, "姊": 551, "始": 552, "姍": 553, "姐": 554, "姑": 555, "姓": 556, "委": 557, "姚": 558, "姨": 559, "姬": 560, "姻": 561, "威": 562, "娑": 563, "娘": 564, "娛": 565, "娶": 566, "娼": 567, "婆": 568, "婊": 569, "婚": 570, "婦": 571, "婪": 572, "媒": 573, "媳": 574, "媽": 575, "嫁": 576, "嫖": 577, "嫩": 578, "嬤": 579, "嬰": 580, "嬸": 581, "子": 582, "孕": 583, "字": 584, "存": 585, "孝": 586, "季": 587, "孤": 588, "孩": 589, "孫": 590, "孵": 591, "學": 592, "它": 593, "宅": 594, "守": 595, "安": 596, "完": 597, "宗": 598, "官": 599, "定": 600, "宜": 601, "客": 602, "宣": 603, "室": 604, "宮": 605, "宰": 606, "害": 607, "宴": 608, "宵": 609, "家": 610, "容": 611, "宿": 612, "寂": 613, "寄": 614, "密": 615, "富": 616, "寒": 617, "寓": 618, "寞": 619, "察": 620, "實": 621, "寧": 622, "審": 623, "寫": 624, "寬": 625, "寮": 626, "寵": 627, "寶": 628, "寸": 629, "寺": 630, "封": 631, "射": 632, "將": 633, "專": 634, "尊": 635, "尋": 636, "對": 637, "導": 638, "小": 639, "少": 640, "尖": 641, "尚": 642, "尤": 643, "尬": 644, "就": 645, "尷": 646, "尺": 647, "尼": 648, "尾": 649, "尿": 650, "局": 651, "屁": 652, "居": 653, "屆": 654, "屈": 655, "屋": 656, "屌": 657, "屎": 658, "屏": 659, "屑": 660, "展": 661, "屜": 662, "屠": 663, "層": 664, "履": 665, "屬": 666, "屯": 667, "山": 668, "岩": 669, "岸": 670, "峰": 671, "島": 672, "峻": 673, "峽": 674, "崛": 675, "崴": 676, "嶄": 677, "巔": 678, "川": 679, "州": 680, "巡": 681, "巢": 682, "工": 683, "左": 684, "巧": 685, "巨": 686, "差": 687, "己": 688, "已": 689, "巴": 690, "巷": 691, "巾": 692, "市": 693, "布": 694, "帆": 695, "希": 696, "帖": 697, "帝": 698, "帥": 699, "師": 700, "席": 701, "帳": 702, "帶": 703, "常": 704, "帽": 705, "幅": 706, "幌": 707, "幕": 708, "幣": 709, "幫": 710, "干": 711, "平": 712, "年": 713, "幸": 714, "幹": 715, "幻": 716, "幼": 717, "幾": 718, "庄": 719, "床": 720, "序": 721, "底": 722, "店": 723, "府": 724, "度": 725, "座": 726, "庫": 727, "庭": 728, "康": 729, "庸": 730, "廁": 731, "廂": 732, "廊": 733, "廖": 734, "廚": 735, "廟": 736, "廠": 737, "廢": 738, "廣": 739, "廬": 740, "廳": 741, "延": 742, "廷": 743, "建": 744, "弄": 745, "弊": 746, "式": 747, "弔": 748, "引": 749, "弘": 750, "弟": 751, "弱": 752, "張": 753, "強": 754, "彈": 755, "彌": 756, "彎": 757, "彙": 758, "形": 759, "彩": 760, "影": 761, "役": 762, "彼": 763, "往": 764, "待": 765, "很": 766, "徊": 767, "律": 768, "後": 769, "徑": 770, "徒": 771, "得": 772, "徘": 773, "徙": 774, "從": 775, "復": 776, "循": 777, "徬": 778, "微": 779, "徵": 780, "德": 781, "徹": 782, "心": 783, "必": 784, "忍": 785, "志": 786, "忘": 787, "忙": 788, "快": 789, "念": 790, "忽": 791, "怎": 792, "怒": 793, "怕": 794, "怖": 795, "思": 796, "怠": 797, "急": 798, "怦": 799, "性": 800, "怨": 801, "怪": 802, "怵": 803, "恃": 804, "恆": 805, "恍": 806, "恐": 807, "恕": 808, "恢": 809, "恤": 810, "恩": 811, "恭": 812, "息": 813, "恰": 814, "悄": 815, "悅": 816, "悉": 817, "悔": 818, "悟": 819, "悠": 820, "患": 821, "您": 822, "悲": 823, "情": 824, "惇": 825, "惋": 826, "惑": 827, "惕": 828, "惘": 829, "惜": 830, "惠": 831, "惡": 832, "惰": 833, "惱": 834, "想": 835, "惶": 836, "惹": 837, "愁": 838, "愈": 839, "愉": 840, "意": 841, "愕": 842, "愚": 843, "愛": 844, "愜": 845, "感": 846, "愣": 847, "愧": 848, "慈": 849, "態": 850, "慌": 851, "慎": 852, "慕": 853, "慘": 854, "慚": 855, "慢": 856, "慣": 857, "慧": 858, "慮": 859, "慰": 860, "慶": 861, "慾": 862, "憂": 863, "憊": 864, "憑": 865, "憩": 866, "憲": 867, "憶": 868, "憾": 869, "懂": 870, "懇": 871, "應": 872, "懲": 873, "懶": 874, "懷": 875, "懼": 876, "戀": 877, "成": 878, "我": 879, "戒": 880, "或": 881, "戚": 882, "截": 883, "戰": 884, "戲": 885, "戴": 886, "戶": 887, "房": 888, "所": 889, "扇": 890, "扉": 891, "手": 892, "才": 893, "扎": 894, "打": 895, "托": 896, "扛": 897, "扣": 898, "扭": 899, "扮": 900, "扯": 901, "扶": 902, "批": 903, "扼": 904, "找": 905, "承": 906, "技": 907, "抄": 908, "把": 909, "抒": 910, "抓": 911, "投": 912, "抖": 913, "抗": 914, "折": 915, "披": 916, "抬": 917, "抱": 918, "抵": 919, "抹": 920, "抽": 921, "拆": 922, "拉": 923, "拋": 924, "拍": 925, "拒": 926, "拓": 927, "拔": 928, "拖": 929, "拘": 930, "拚": 931, "招": 932, "拜": 933, "括": 934, "拯": 935, "拱": 936, "拳": 937, "拼": 938, "拾": 939, "拿": 940, "持": 941, "指": 942, "按": 943, "挑": 944, "挖": 945, "挫": 946, "振": 947, "捍": 948, "捐": 949, "捕": 950, "捨": 951, "捲": 952, "捷": 953, "掃": 954, "授": 955, "掉": 956, "掌": 957, "掏": 958, "排": 959, "掘": 960, "掙": 961, "掛": 962, "掠": 963, "採": 964, "探": 965, "接": 966, "控": 967, "推": 968, "掩": 969, "措": 970, "掰": 971, "揉": 972, "描": 973, "提": 974, "插": 975, "揚": 976, "換": 977, "握": 978, "揣": 979, "揭": 980, "揮": 981, "援": 982, "揹": 983, "損": 984, "搏": 985, "搖": 986, "搗": 987, "搜": 988, "搞": 989, "搬": 990, "搭": 991, "搶": 992, "摔": 993, "摘": 994, "摟": 995, "摧": 996, "摩": 997, "摯": 998, "摸": 999, "撇": 1000, "撒": 1001, "撞": 1002, "撤": 1003, "撥": 1004, "撫": 1005, "播": 1006, "撲": 1007, "撿": 1008, "擁": 1009, "擅": 1010, "擇": 1011, "擊": 1012, "擋": 1013, "操": 1014, "擎": 1015, "擔": 1016, "據": 1017, "擠": 1018, "擦": 1019, "擬": 1020, "擱": 1021, "擲": 1022, "擴": 1023, "擺": 1024, "擾": 1025, "攜": 1026, "攝": 1027, "攤": 1028, "支": 1029, "收": 1030, "攸": 1031, "改": 1032, "攻": 1033, "放": 1034, "政": 1035, "故": 1036, "效": 1037, "敏": 1038, "救": 1039, "敗": 1040, "敘": 1041, "教": 1042, "敝": 1043, "敢": 1044, "散": 1045, "敦": 1046, "敬": 1047, "敲": 1048, "整": 1049, "敵": 1050, "數": 1051, "斂": 1052, "文": 1053, "斌": 1054, "料": 1055, "斜": 1056, "斤": 1057, "斥": 1058, "斧": 1059, "斯": 1060, "新": 1061, "斷": 1062, "方": 1063, "於": 1064, "施": 1065, "旁": 1066, "旅": 1067, "旋": 1068, "族": 1069, "旗": 1070, "既": 1071, "日": 1072, "旦": 1073, "旨": 1074, "早": 1075, "旬": 1076, "旭": 1077, "旺": 1078, "昂": 1079, "昇": 1080, "昌": 1081, "明": 1082, "昏": 1083, "易": 1084, "昔": 1085, "星": 1086, "映": 1087, "春": 1088, "昧": 1089, "昨": 1090, "是": 1091, "昴": 1092, "時": 1093, "晃": 1094, "晚": 1095, "晨": 1096, "普": 1097, "景": 1098, "晰": 1099, "晴": 1100, "晶": 1101, "智": 1102, "晾": 1103, "暄": 1104, "暈": 1105, "暑": 1106, "暖": 1107, "暗": 1108, "暫": 1109, "暱": 1110, "暴": 1111, "曆": 1112, "曉": 1113, "曙": 1114, "曝": 1115, "曬": 1116, "曲": 1117, "更": 1118, "書": 1119, "曹": 1120, "曾": 1121, "替": 1122, "最": 1123, "會": 1124, "月": 1125, "有": 1126, "朋": 1127, "服": 1128, "朕": 1129, "朗": 1130, "望": 1131, "朝": 1132, "期": 1133, "木": 1134, "未": 1135, "末": 1136, "本": 1137, "札": 1138, "朱": 1139, "朵": 1140, "朽": 1141, "杉": 1142, "李": 1143, "材": 1144, "村": 1145, "杖": 1146, "杜": 1147, "束": 1148, "杭": 1149, "杯": 1150, "東": 1151, "松": 1152, "板": 1153, "枉": 1154, "析": 1155, "林": 1156, "枚": 1157, "果": 1158, "枝": 1159, "枯": 1160, "架": 1161, "柏": 1162, "某": 1163, "染": 1164, "柔": 1165, "柚": 1166, "查": 1167, "柯": 1168, "柳": 1169, "柴": 1170, "柵": 1171, "柺": 1172, "柿": 1173, "栗": 1174, "校": 1175, "株": 1176, "核": 1177, "根": 1178, "格": 1179, "栽": 1180, "桃": 1181, "框": 1182, "案": 1183, "桌": 1184, "桶": 1185, "桿": 1186, "梅": 1187, "梗": 1188, "條": 1189, "梨": 1190, "梯": 1191, "梳": 1192, "棄": 1193, "棉": 1194, "棋": 1195, "棒": 1196, "棚": 1197, "棟": 1198, "森": 1199, "棲": 1200, "棵": 1201, "椅": 1202, "植": 1203, "椒": 1204, "椰": 1205, "楊": 1206, "楚": 1207, "業": 1208, "極": 1209, "概": 1210, "榕": 1211, "榜": 1212, "榮": 1213, "構": 1214, "槍": 1215, "樁": 1216, "樂": 1217, "樑": 1218, "樓": 1219, "標": 1220, "樞": 1221, "模": 1222, "樣": 1223, "樵": 1224, "樸": 1225, "樹": 1226, "樽": 1227, "橋": 1228, "橘": 1229, "橙": 1230, "機": 1231, "橡": 1232, "檔": 1233, "檢": 1234, "檬": 1235, "檯": 1236, "檸": 1237, "檻": 1238, "櫃": 1239, "欄": 1240, "欉": 1241, "權": 1242, "欠": 1243, "次": 1244, "欣": 1245, "欲": 1246, "欸": 1247, "欽": 1248, "款": 1249, "歉": 1250, "歌": 1251, "歐": 1252, "歡": 1253, "止": 1254, "正": 1255, "此": 1256, "步": 1257, "武": 1258, "歧": 1259, "歲": 1260, "歷": 1261, "歸": 1262, "死": 1263, "殊": 1264, "殘": 1265, "段": 1266, "殷": 1267, "殺": 1268, "殼": 1269, "殿": 1270, "毀": 1271, "毋": 1272, "母": 1273, "每": 1274, "毒": 1275, "比": 1276, "毛": 1277, "毫": 1278, "氏": 1279, "民": 1280, "氛": 1281, "氣": 1282, "氧": 1283, "氫": 1284, "氰": 1285, "水": 1286, "永": 1287, "氾": 1288, "汁": 1289, "求": 1290, "汐": 1291, "汗": 1292, "汙": 1293, "汛": 1294, "汝": 1295, "江": 1296, "池": 1297, "污": 1298, "汰": 1299, "決": 1300, "汽": 1301, "汾": 1302, "沈": 1303, "沉": 1304, "沐": 1305, "沒": 1306, "沖": 1307, "沙": 1308, "沛": 1309, "没": 1310, "沮": 1311, "沱": 1312, "河": 1313, "油": 1314, "治": 1315, "況": 1316, "泉": 1317, "法": 1318, "泛": 1319, "泡": 1320, "波": 1321, "泣": 1322, "泥": 1323, "注": 1324, "泰": 1325, "泳": 1326, "洋": 1327, "洗": 1328, "洛": 1329, "洞": 1330, "津": 1331, "洱": 1332, "洲": 1333, "活": 1334, "洽": 1335, "派": 1336, "流": 1337, "浪": 1338, "浮": 1339, "浴": 1340, "海": 1341, "消": 1342, "涉": 1343, "涯": 1344, "液": 1345, "涵": 1346, "涸": 1347, "涼": 1348, "淇": 1349, "淋": 1350, "淑": 1351, "淒": 1352, "淘": 1353, "淚": 1354, "淡": 1355, "淨": 1356, "淪": 1357, "深": 1358, "混": 1359, "淺": 1360, "添": 1361, "清": 1362, "減": 1363, "渡": 1364, "渥": 1365, "測": 1366, "港": 1367, "渲": 1368, "渴": 1369, "游": 1370, "渾": 1371, "湊": 1372, "湍": 1373, "湖": 1374, "湧": 1375, "湯": 1376, "源": 1377, "準": 1378, "溝": 1379, "溪": 1380, "溫": 1381, "溺": 1382, "滂": 1383, "滅": 1384, "滋": 1385, "滌": 1386, "滑": 1387, "滯": 1388, "滴": 1389, "滾": 1390, "滿": 1391, "漁": 1392, "漂": 1393, "漆": 1394, "漏": 1395, "演": 1396, "漠": 1397, "漢": 1398, "漫": 1399, "漲": 1400, "漸": 1401, "潑": 1402, "潔": 1403, "潛": 1404, "潤": 1405, "潮": 1406, "澄": 1407, "澎": 1408, "澤": 1409, "澳": 1410, "激": 1411, "濃": 1412, "濕": 1413, "濟": 1414, "濫": 1415, "濱": 1416, "濾": 1417, "瀑": 1418, "瀕": 1419, "灌": 1420, "灑": 1421, "灘": 1422, "灣": 1423, "火": 1424, "灰": 1425, "災": 1426, "炎": 1427, "炒": 1428, "炫": 1429, "炸": 1430, "為": 1431, "烈": 1432, "烊": 1433, "烏": 1434, "烤": 1435, "烹": 1436, "無": 1437, "焦": 1438, "焰": 1439, "然": 1440, "煎": 1441, "煙": 1442, "照": 1443, "煩": 1444, "煮": 1445, "熊": 1446, "熟": 1447, "熬": 1448, "熱": 1449, "燃": 1450, "燈": 1451, "燒": 1452, "燙": 1453, "營": 1454, "燥": 1455, "燦": 1456, "爆": 1457, "爍": 1458, "爐": 1459, "爛": 1460, "爪": 1461, "爬": 1462, "爭": 1463, "爲": 1464, "父": 1465, "爸": 1466, "爹": 1467, "爺": 1468, "爽": 1469, "爾": 1470, "牆": 1471, "片": 1472, "版": 1473, "牌": 1474, "牙": 1475, "牛": 1476, "牠": 1477, "牡": 1478, "物": 1479, "牴": 1480, "特": 1481, "牽": 1482, "犬": 1483, "犯": 1484, "狀": 1485, "狗": 1486, "狠": 1487, "狼": 1488, "猛": 1489, "猜": 1490, "猩": 1491, "猴": 1492, "猶": 1493, "猿": 1494, "獄": 1495, "獅": 1496, "獎": 1497, "獨": 1498, "獲": 1499, "獵": 1500, "獸": 1501, "獻": 1502, "率": 1503, "玉": 1504, "王": 1505, "玩": 1506, "玻": 1507, "珍": 1508, "珠": 1509, "班": 1510, "現": 1511, "球": 1512, "理": 1513, "琪": 1514, "琴": 1515, "瑋": 1516, "瑜": 1517, "瑟": 1518, "瑩": 1519, "瑪": 1520, "瑰": 1521, "璃": 1522, "環": 1523, "瓜": 1524, "瓦": 1525, "瓶": 1526, "甄": 1527, "甘": 1528, "甚": 1529, "甜": 1530, "生": 1531, "產": 1532, "用": 1533, "甩": 1534, "甫": 1535, "田": 1536, "由": 1537, "甲": 1538, "申": 1539, "男": 1540, "町": 1541, "界": 1542, "畔": 1543, "留": 1544, "畢": 1545, "略": 1546, "番": 1547, "畫": 1548, "異": 1549, "當": 1550, "疊": 1551, "疏": 1552, "疑": 1553, "疙": 1554, "疫": 1555, "疲": 1556, "疼": 1557, "疾": 1558, "病": 1559, "症": 1560, "痕": 1561, "痛": 1562, "痰": 1563, "痴": 1564, "瘋": 1565, "瘟": 1566, "瘦": 1567, "瘩": 1568, "療": 1569, "癌": 1570, "癡": 1571, "癮": 1572, "癱": 1573, "登": 1574, "發": 1575, "白": 1576, "百": 1577, "的": 1578, "皆": 1579, "皇": 1580, "皮": 1581, "皺": 1582, "益": 1583, "盎": 1584, "盒": 1585, "盔": 1586, "盛": 1587, "盜": 1588, "盞": 1589, "盟": 1590, "盡": 1591, "監": 1592, "盤": 1593, "盪": 1594, "目": 1595, "盲": 1596, "直": 1597, "相": 1598, "盼": 1599, "盾": 1600, "省": 1601, "眉": 1602, "看": 1603, "真": 1604, "眠": 1605, "眷": 1606, "眼": 1607, "眾": 1608, "睛": 1609, "睡": 1610, "督": 1611, "睦": 1612, "瞧": 1613, "瞪": 1614, "瞬": 1615, "瞭": 1616, "瞻": 1617, "矛": 1618, "知": 1619, "矩": 1620, "短": 1621, "矮": 1622, "矲": 1623, "石": 1624, "砂": 1625, "研": 1626, "砲": 1627, "破": 1628, "硃": 1629, "硬": 1630, "碌": 1631, "碎": 1632, "碑": 1633, "碗": 1634, "碟": 1635, "碧": 1636, "碩": 1637, "碰": 1638, "碳": 1639, "確": 1640, "碼": 1641, "碾": 1642, "磁": 1643, "磐": 1644, "磚": 1645, "磨": 1646, "礎": 1647, "礙": 1648, "示": 1649, "社": 1650, "祈": 1651, "祉": 1652, "祕": 1653, "祖": 1654, "祝": 1655, "神": 1656, "祟": 1657, "祥": 1658, "票": 1659, "祭": 1660, "��": 1661, "禁": 1662, "禍": 1663, "福": 1664, "禦": 1665, "禧": 1666, "禮": 1667, "禱": 1668, "禿": 1669, "秀": 1670, "私": 1671, "秉": 1672, "秋": 1673, "科": 1674, "秒": 1675, "秘": 1676, "租": 1677, "秧": 1678, "秩": 1679, "移": 1680, "稅": 1681, "程": 1682, "稍": 1683, "稚": 1684, "種": 1685, "稱": 1686, "稻": 1687, "稿": 1688, "穀": 1689, "積": 1690, "穗": 1691, "穩": 1692, "穴": 1693, "究": 1694, "空": 1695, "穿": 1696, "突": 1697, "窗": 1698, "窮": 1699, "竅": 1700, "立": 1701, "站": 1702, "竟": 1703, "章": 1704, "童": 1705, "端": 1706, "競": 1707, "竹": 1708, "竿": 1709, "笑": 1710, "符": 1711, "第": 1712, "筆": 1713, "等": 1714, "筋": 1715, "筐": 1716, "筒": 1717, "答": 1718, "策": 1719, "箕": 1720, "算": 1721, "管": 1722, "箱": 1723, "節": 1724, "範": 1725, "篇": 1726, "築": 1727, "篩": 1728, "篷": 1729, "簡": 1730, "簷": 1731, "簽": 1732, "簿": 1733, "籃": 1734, "籌": 1735, "籍": 1736, "籠": 1737, "籤": 1738, "籮": 1739, "籲": 1740, "米": 1741, "籽": 1742, "粉": 1743, "粒": 1744, "粗": 1745, "粥": 1746, "粹": 1747, "精": 1748, "糊": 1749, "糕": 1750, "糖": 1751, "糞": 1752, "糟": 1753, "糧": 1754, "糬": 1755, "糰": 1756, "系": 1757, "糾": 1758, "紀": 1759, "約": 1760, "紅": 1761, "紋": 1762, "納": 1763, "紐": 1764, "紓": 1765, "純": 1766, "紙": 1767, "級": 1768, "紛": 1769, "素": 1770, "紡": 1771, "索": 1772, "紫": 1773, "累": 1774, "細": 1775, "紹": 1776, "終": 1777, "組": 1778, "絆": 1779, "結": 1780, "絕": 1781, "絡": 1782, "給": 1783, "絨": 1784, "統": 1785, "絲": 1786, "綁": 1787, "經": 1788, "綜": 1789, "綠": 1790, "維": 1791, "綱": 1792, "網": 1793, "綿": 1794, "緊": 1795, "緒": 1796, "線": 1797, "締": 1798, "緣": 1799, "編": 1800, "緩": 1801, "練": 1802, "緻": 1803, "縈": 1804, "縝": 1805, "縣": 1806, "縫": 1807, "縮": 1808, "縱": 1809, "總": 1810, "績": 1811, "繁": 1812, "織": 1813, "繞": 1814, "繩": 1815, "繪": 1816, "繫": 1817, "繳": 1818, "繹": 1819, "繼": 1820, "續": 1821, "纏": 1822, "纜": 1823, "缸": 1824, "缺": 1825, "罄": 1826, "罐": 1827, "罩": 1828, "罪": 1829, "置": 1830, "罰": 1831, "署": 1832, "罵": 1833, "罷": 1834, "罹": 1835, "羅": 1836, "羈": 1837, "羊": 1838, "美": 1839, "羞": 1840, "群": 1841, "羨": 1842, "義": 1843, "羽": 1844, "翁": 1845, "翅": 1846, "習": 1847, "翹": 1848, "翻": 1849, "翼": 1850, "耀": 1851, "老": 1852, "考": 1853, "者": 1854, "而": 1855, "耍": 1856, "耐": 1857, "耕": 1858, "耗": 1859, "耘": 1860, "耳": 1861, "耶": 1862, "耽": 1863, "聆": 1864, "聊": 1865, "聖": 1866, "聘": 1867, "聚": 1868, "聞": 1869, "聯": 1870, "聰": 1871, "聲": 1872, "聳": 1873, "職": 1874, "聽": 1875, "肅": 1876, "肉": 1877, "肋": 1878, "肘": 1879, "肚": 1880, "肝": 1881, "股": 1882, "肢": 1883, "肥": 1884, "肩": 1885, "肯": 1886, "育": 1887, "肺": 1888, "胃": 1889, "背": 1890, "胎": 1891, "胖": 1892, "胞": 1893, "胡": 1894, "胯": 1895, "胸": 1896, "能": 1897, "脆": 1898, "脈": 1899, "脖": 1900, "脫": 1901, "脹": 1902, "脾": 1903, "腐": 1904, "腔": 1905, "腦": 1906, "腫": 1907, "腮": 1908, "腰": 1909, "腳": 1910, "腸": 1911, "腹": 1912, "腿": 1913, "膀": 1914, "膏": 1915, "膠": 1916, "膨": 1917, "膩": 1918, "膽": 1919, "臂": 1920, "臃": 1921, "臉": 1922, "臟": 1923, "臣": 1924, "臨": 1925, "自": 1926, "臭": 1927, "至": 1928, "致": 1929, "臺": 1930, "舅": 1931, "與": 1932, "興": 1933, "舉": 1934, "舊": 1935, "舌": 1936, "舍": 1937, "舒": 1938, "舔": 1939, "舞": 1940, "舟": 1941, "航": 1942, "般": 1943, "船": 1944, "艦": 1945, "良": 1946, "艱": 1947, "色": 1948, "艷": 1949, "芋": 1950, "芒": 1951, "芙": 1952, "芬": 1953, "芭": 1954, "花": 1955, "芳": 1956, "芹": 1957, "芽": 1958, "苓": 1959, "苗": 1960, "苟": 1961, "若": 1962, "苦": 1963, "英": 1964, "茂": 1965, "范": 1966, "茄": 1967, "茫": 1968, "茱": 1969, "茲": 1970, "茶": 1971, "草": 1972, "荒": 1973, "荷": 1974, "莊": 1975, "莎": 1976, "莓": 1977, "莫": 1978, "菁": 1979, "菇": 1980, "菌": 1981, "菜": 1982, "華": 1983, "菲": 1984, "菸": 1985, "萄": 1986, "萊": 1987, "萬": 1988, "萱": 1989, "落": 1990, "葉": 1991, "著": 1992, "葛": 1993, "葡": 1994, "董": 1995, "葬": 1996, "蒂": 1997, "蒐": 1998, "蒙": 1999, "蒸": 2000, "蒼": 2001, "蓋": 2002, "蓮": 2003, "蔔": 2004, "蔚": 2005, "蔡": 2006, "蔣": 2007, "蔥": 2008, "蔭": 2009, "蕾": 2010, "薄": 2011, "薏": 2012, "薑": 2013, "薦": 2014, "薩": 2015, "薪": 2016, "薯": 2017, "藉": 2018, "藍": 2019, "藏": 2020, "藝": 2021, "藤": 2022, "藥": 2023, "藩": 2024, "蘆": 2025, "蘊": 2026, "蘋": 2027, "蘑": 2028, "蘭": 2029, "蘿": 2030, "虎": 2031, "虐": 2032, "處": 2033, "虛": 2034, "虞": 2035, "號": 2036, "虧": 2037, "蚊": 2038, "蚤": 2039, "蛇": 2040, "蛋": 2041, "蛙": 2042, "蛛": 2043, "蛻": 2044, "蜂": 2045, "蜘": 2046, "蜜": 2047, "蝦": 2048, "螃": 2049, "融": 2050, "螞": 2051, "螢": 2052, "螺": 2053, "蟬": 2054, "蟲": 2055, "蟹": 2056, "蟻": 2057, "蠅": 2058, "蠢": 2059, "蠱": 2060, "蠻": 2061, "血": 2062, "行": 2063, "衍": 2064, "術": 2065, "街": 2066, "衛": 2067, "衝": 2068, "衡": 2069, "衣": 2070, "表": 2071, "衫": 2072, "衰": 2073, "袋": 2074, "袖": 2075, "被": 2076, "袱": 2077, "裁": 2078, "裂": 2079, "裙": 2080, "補": 2081, "裝": 2082, "裡": 2083, "裸": 2084, "製": 2085, "複": 2086, "褐": 2087, "褲": 2088, "襄": 2089, "襪": 2090, "襲": 2091, "西": 2092, "要": 2093, "覆": 2094, "見": 2095, "規": 2096, "覓": 2097, "視": 2098, "親": 2099, "覺": 2100, "覽": 2101, "觀": 2102, "角": 2103, "解": 2104, "觸": 2105, "言": 2106, "訂": 2107, "計": 2108, "訊": 2109, "討": 2110, "訐": 2111, "訓": 2112, "訕": 2113, "託": 2114, "記": 2115, "訝": 2116, "訟": 2117, "訣": 2118, "訪": 2119, "設": 2120, "許": 2121, "訴": 2122, "診": 2123, "註": 2124, "詐": 2125, "評": 2126, "詞": 2127, "詢": 2128, "試": 2129, "詩": 2130, "詬": 2131, "詭": 2132, "話": 2133, "該": 2134, "詳": 2135, "詹": 2136, "誇": 2137, "誌": 2138, "認": 2139, "誓": 2140, "誕": 2141, "誘": 2142, "語": 2143, "誠": 2144, "誡": 2145, "誣": 2146, "誤": 2147, "說": 2148, "誰": 2149, "課": 2150, "誼": 2151, "調": 2152, "談": 2153, "請": 2154, "諒": 2155, "論": 2156, "諮": 2157, "諸": 2158, "諾": 2159, "謀": 2160, "謂": 2161, "謄": 2162, "謊": 2163, "講": 2164, "謝": 2165, "謠": 2166, "謹": 2167, "證": 2168, "識": 2169, "譚": 2170, "譜": 2171, "警": 2172, "譯": 2173, "議": 2174, "護": 2175, "譽": 2176, "讀": 2177, "變": 2178, "讓": 2179, "讚": 2180, "谷": 2181, "豆": 2182, "豈": 2183, "豐": 2184, "豚": 2185, "象": 2186, "豪": 2187, "豫": 2188, "豬": 2189, "貌": 2190, "貓": 2191, "貝": 2192, "貞": 2193, "負": 2194, "財": 2195, "貢": 2196, "貧": 2197, "貨": 2198, "販": 2199, "貪": 2200, "貫": 2201, "責": 2202, "貲": 2203, "貴": 2204, "買": 2205, "貸": 2206, "費": 2207, "貼": 2208, "貿": 2209, "資": 2210, "賊": 2211, "賓": 2212, "賞": 2213, "賠": 2214, "賢": 2215, "賣": 2216, "賤": 2217, "賦": 2218, "質": 2219, "賭": 2220, "賴": 2221, "賺": 2222, "購": 2223, "賽": 2224, "贈": 2225, "贊": 2226, "贏": 2227, "赤": 2228, "赫": 2229, "走": 2230, "起": 2231, "趁": 2232, "超": 2233, "越": 2234, "趕": 2235, "趟": 2236, "趣": 2237, "趨": 2238, "足": 2239, "趴": 2240, "跆": 2241, "跋": 2242, "跌": 2243, "跑": 2244, "跚": 2245, "距": 2246, "跟": 2247, "跡": 2248, "跨": 2249, "路": 2250, "跳": 2251, "踉": 2252, "踏": 2253, "踐": 2254, "踩": 2255, "踴": 2256, "踹": 2257, "蹄": 2258, "蹌": 2259, "蹟": 2260, "蹣": 2261, "蹤": 2262, "蹦": 2263, "蹲": 2264, "躁": 2265, "躍": 2266, "身": 2267, "躲": 2268, "躺": 2269, "軀": 2270, "車": 2271, "軌": 2272, "軍": 2273, "軟": 2274, "較": 2275, "載": 2276, "輔": 2277, "輕": 2278, "輩": 2279, "輪": 2280, "輯": 2281, "輸": 2282, "輾": 2283, "輿": 2284, "轄": 2285, "轉": 2286, "轎": 2287, "辛": 2288, "辜": 2289, "辣": 2290, "辦": 2291, "辨": 2292, "辭": 2293, "辯": 2294, "辱": 2295, "農": 2296, "迅": 2297, "迎": 2298, "近": 2299, "返": 2300, "迪": 2301, "迫": 2302, "述": 2303, "迴": 2304, "迷": 2305, "追": 2306, "退": 2307, "送": 2308, "逃": 2309, "逆": 2310, "透": 2311, "逐": 2312, "途": 2313, "逕": 2314, "逗": 2315, "這": 2316, "通": 2317, "逛": 2318, "逝": 2319, "逞": 2320, "速": 2321, "造": 2322, "逢": 2323, "連": 2324, "週": 2325, "進": 2326, "逼": 2327, "逾": 2328, "遁": 2329, "遇": 2330, "遊": 2331, "運": 2332, "遍": 2333, "過": 2334, "道": 2335, "達": 2336, "違": 2337, "遙": 2338, "遜": 2339, "遞": 2340, "遠": 2341, "適": 2342, "遭": 2343, "遲": 2344, "遴": 2345, "遵": 2346, "遷": 2347, "選": 2348, "遺": 2349, "遼": 2350, "遽": 2351, "避": 2352, "邀": 2353, "邁": 2354, "還": 2355, "邊": 2356, "邏": 2357, "那": 2358, "邦": 2359, "邪": 2360, "邵": 2361, "郁": 2362, "郊": 2363, "郎": 2364, "郝": 2365, "部": 2366, "郭": 2367, "都": 2368, "鄉": 2369, "鄧": 2370, "鄭": 2371, "鄰": 2372, "配": 2373, "酒": 2374, "酗": 2375, "酪": 2376, "酬": 2377, "酵": 2378, "酷": 2379, "酸": 2380, "醉": 2381, "醒": 2382, "醜": 2383, "醫": 2384, "醬": 2385, "采": 2386, "釋": 2387, "里": 2388, "重": 2389, "野": 2390, "量": 2391, "釐": 2392, "金": 2393, "針": 2394, "釣": 2395, "鈴": 2396, "鉅": 2397, "鉤": 2398, "銀": 2399, "銘": 2400, "銜": 2401, "銷": 2402, "鋒": 2403, "鋪": 2404, "鋸": 2405, "鋼": 2406, "錄": 2407, "錢": 2408, "錦": 2409, "錨": 2410, "錯": 2411, "錶": 2412, "鍊": 2413, "鍋": 2414, "鍛": 2415, "鍵": 2416, "鍾": 2417, "鎂": 2418, "鎖": 2419, "鎮": 2420, "鏈": 2421, "鏡": 2422, "鐘": 2423, "鐵": 2424, "鑑": 2425, "鑰": 2426, "鑼": 2427, "長": 2428, "門": 2429, "閃": 2430, "閉": 2431, "開": 2432, "閒": 2433, "間": 2434, "閱": 2435, "闆": 2436, "闊": 2437, "關": 2438, "闢": 2439, "阱": 2440, "防": 2441, "阻": 2442, "阿": 2443, "陀": 2444, "附": 2445, "陌": 2446, "降": 2447, "限": 2448, "院": 2449, "陣": 2450, "除": 2451, "陪": 2452, "陰": 2453, "陳": 2454, "陷": 2455, "陸": 2456, "陽": 2457, "隆": 2458, "隊": 2459, "階": 2460, "隔": 2461, "際": 2462, "障": 2463, "隧": 2464, "隨": 2465, "險": 2466, "隱": 2467, "隻": 2468, "雀": 2469, "雄": 2470, "雅": 2471, "集": 2472, "雇": 2473, "雌": 2474, "雕": 2475, "雖": 2476, "雙": 2477, "雛": 2478, "雜": 2479, "雞": 2480, "離": 2481, "難": 2482, "雨": 2483, "雪": 2484, "雲": 2485, "零": 2486, "雷": 2487, "電": 2488, "需": 2489, "霄": 2490, "震": 2491, "霉": 2492, "霍": 2493, "霧": 2494, "露": 2495, "霸": 2496, "霹": 2497, "靂": 2498, "靈": 2499, "青": 2500, "靜": 2501, "非": 2502, "靠": 2503, "靡": 2504, "面": 2505, "革": 2506, "靭": 2507, "鞋": 2508, "鞭": 2509, "韋": 2510, "韓": 2511, "音": 2512, "韻": 2513, "響": 2514, "頁": 2515, "頂": 2516, "頃": 2517, "項": 2518, "順": 2519, "須": 2520, "預": 2521, "頓": 2522, "頗": 2523, "領": 2524, "頭": 2525, "頰": 2526, "頸": 2527, "頻": 2528, "顆": 2529, "題": 2530, "額": 2531, "顏": 2532, "願": 2533, "類": 2534, "顧": 2535, "顯": 2536, "顰": 2537, "風": 2538, "颱": 2539, "飄": 2540, "飆": 2541, "飛": 2542, "食": 2543, "飩": 2544, "飪": 2545, "飯": 2546, "飲": 2547, "飽": 2548, "飾": 2549, "餃": 2550, "餅": 2551, "養": 2552, "餐": 2553, "餓": 2554, "餘": 2555, "餚": 2556, "餛": 2557, "餡": 2558, "館": 2559, "餵": 2560, "饋": 2561, "饒": 2562, "饗": 2563, "首": 2564, "香": 2565, "馥": 2566, "馨": 2567, "馬": 2568, "駁": 2569, "駐": 2570, "駕": 2571, "駛": 2572, "駭": 2573, "騎": 2574, "騙": 2575, "騰": 2576, "騷": 2577, "驅": 2578, "驕": 2579, "驗": 2580, "驚": 2581, "驟": 2582, "骨": 2583, "髒": 2584, "體": 2585, "高": 2586, "髮": 2587, "鬆": 2588, "鬍": 2589, "鬚": 2590, "鬥": 2591, "鬧": 2592, "鬼": 2593, "魂": 2594, "魄": 2595, "魔": 2596, "魚": 2597, "魯": 2598, "魷": 2599, "鮪": 2600, "鮭": 2601, "鮮": 2602, "鯊": 2603, "鯛": 2604, "鯨": 2605, "鰈": 2606, "鰜": 2607, "鰭": 2608, "鰻": 2609, "鳥": 2610, "鳩": 2611, "鳳": 2612, "鳴": 2613, "鴉": 2614, "鴨": 2615, "鴻": 2616, "鵝": 2617, "鵲": 2618, "鶯": 2619, "鶴": 2620, "鷹": 2621, "鹹": 2622, "鹽": 2623, "鹿": 2624, "麗": 2625, "麥": 2626, "麵": 2627, "麻": 2628, "麼": 2629, "麽": 2630, "黃": 2631, "黎": 2632, "黑": 2633, "默": 2634, "點": 2635, "黨": 2636, "鼎": 2637, "鼓": 2638, "鼻": 2639, "齁": 2640, "齊": 2641, "齡": 2642, "龍": 2643, "龐": 2644, "龜": 2645, "a": 2646, "b": 2647, "f": 2648, "g": 2649, "i": 2650, "n": 2651, "p": 2652, "t": 2653, "|": 0, "[UNK]": 2654, "[PAD]": 2655}
|