AigizK commited on
Commit
6e13c6f
1 Parent(s): 153d3f5

End of training

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ model.safetensors.bak filter=lfs diff=lfs merge=lfs -text
.ipynb_checkpoints/config-checkpoint.json ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_name_or_path": "facebook/w2v-bert-2.0",
3
+ "activation_dropout": 0.0,
4
+ "adapter_act": "relu",
5
+ "adapter_kernel_size": 3,
6
+ "adapter_stride": 2,
7
+ "add_adapter": true,
8
+ "apply_spec_augment": false,
9
+ "architectures": [
10
+ "Wav2Vec2BertForCTC"
11
+ ],
12
+ "attention_dropout": 0.0,
13
+ "bos_token_id": 1,
14
+ "classifier_proj_size": 768,
15
+ "codevector_dim": 768,
16
+ "conformer_conv_dropout": 0.1,
17
+ "contrastive_logits_temperature": 0.1,
18
+ "conv_depthwise_kernel_size": 31,
19
+ "ctc_loss_reduction": "mean",
20
+ "ctc_zero_infinity": false,
21
+ "diversity_loss_weight": 0.1,
22
+ "eos_token_id": 2,
23
+ "feat_proj_dropout": 0.0,
24
+ "feat_quantizer_dropout": 0.0,
25
+ "feature_projection_input_dim": 160,
26
+ "final_dropout": 0.1,
27
+ "hidden_act": "swish",
28
+ "hidden_dropout": 0.0,
29
+ "hidden_size": 1024,
30
+ "initializer_range": 0.02,
31
+ "intermediate_size": 4096,
32
+ "layer_norm_eps": 1e-05,
33
+ "layerdrop": 0.0,
34
+ "left_max_position_embeddings": 64,
35
+ "mask_feature_length": 10,
36
+ "mask_feature_min_masks": 0,
37
+ "mask_feature_prob": 0.0,
38
+ "mask_time_length": 10,
39
+ "mask_time_min_masks": 2,
40
+ "mask_time_prob": 0.0,
41
+ "max_source_positions": 5000,
42
+ "model_type": "wav2vec2-bert",
43
+ "num_adapter_layers": 1,
44
+ "num_attention_heads": 16,
45
+ "num_codevector_groups": 2,
46
+ "num_codevectors_per_group": 320,
47
+ "num_hidden_layers": 24,
48
+ "num_negatives": 100,
49
+ "output_hidden_size": 1024,
50
+ "pad_token_id": 39,
51
+ "position_embeddings_type": "relative_key",
52
+ "proj_codevector_dim": 768,
53
+ "right_max_position_embeddings": 8,
54
+ "rotary_embedding_base": 10000,
55
+ "tdnn_dilation": [
56
+ 1,
57
+ 2,
58
+ 3,
59
+ 1,
60
+ 1
61
+ ],
62
+ "tdnn_dim": [
63
+ 512,
64
+ 512,
65
+ 512,
66
+ 512,
67
+ 1500
68
+ ],
69
+ "tdnn_kernel": [
70
+ 5,
71
+ 3,
72
+ 3,
73
+ 1,
74
+ 1
75
+ ],
76
+ "torch_dtype": "float32",
77
+ "transformers_version": "4.40.1",
78
+ "use_intermediate_ffn_before_adapter": false,
79
+ "use_weighted_layer_sum": false,
80
+ "vocab_size": 42,
81
+ "xvector_output_dim": 512
82
+ }
.ipynb_checkpoints/preprocessor_config-checkpoint.json ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "feature_extractor_type": "SeamlessM4TFeatureExtractor",
3
+ "feature_size": 80,
4
+ "num_mel_bins": 80,
5
+ "padding_side": "right",
6
+ "padding_value": 1,
7
+ "processor_class": "Wav2Vec2BertProcessor",
8
+ "return_attention_mask": true,
9
+ "sampling_rate": 16000,
10
+ "stride": 2
11
+ }
README.md CHANGED
@@ -16,6 +16,14 @@ should probably proofread and complete it, then remove this comment. -->
16
  # w2v-bert-2.0-mhr-CV17.0
17
 
18
  This model is a fine-tuned version of [facebook/w2v-bert-2.0](https://huggingface.co/facebook/w2v-bert-2.0) on the common_voice_17_0 dataset.
 
 
 
 
 
 
 
 
19
 
20
  ## Model description
21
 
 
16
  # w2v-bert-2.0-mhr-CV17.0
17
 
18
  This model is a fine-tuned version of [facebook/w2v-bert-2.0](https://huggingface.co/facebook/w2v-bert-2.0) on the common_voice_17_0 dataset.
19
+ It achieves the following results on the evaluation set:
20
+ - eval_loss: inf
21
+ - eval_wer: 0.9785
22
+ - eval_runtime: 543.2858
23
+ - eval_samples_per_second: 27.84
24
+ - eval_steps_per_second: 3.481
25
+ - epoch: 0.9386
26
+ - step: 12300
27
 
28
  ## Model description
29
 
model.safetensors CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:87971d7bbf1ffdc48f0bb2b14e3e9ab9823c43e2254d951d082ba68bb21b5597
3
  size 2422986760
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a42f887de557465e18bb4032db07f831766ae3b687b493d42190a6b833059ac8
3
  size 2422986760
model.safetensors.bak ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:87971d7bbf1ffdc48f0bb2b14e3e9ab9823c43e2254d951d082ba68bb21b5597
3
+ size 2422986760
w2v-bert-v2.ipynb ADDED
@@ -0,0 +1,364 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {},
6
+ "source": [
7
+ "# fine-tune wav2vec BERT v2\n",
8
+ "\n",
9
+ "[![](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/phineas-pta/fine-tune-whisper-vi/blob/main/train/w2v-bert-v2.ipynb)\n",
10
+ "\n",
11
+ "on colab: mount gdrive using GUI before training\n",
12
+ "\n",
13
+ "on kaggle: select kaggle free T4×2 for auto double batch size"
14
+ ]
15
+ },
16
+ {
17
+ "cell_type": "code",
18
+ "execution_count": null,
19
+ "metadata": {
20
+ "collapsed": false,
21
+ "jupyter": {
22
+ "outputs_hidden": false
23
+ },
24
+ "trusted": true
25
+ },
26
+ "outputs": [],
27
+ "source": [
28
+ "from huggingface_hub import notebook_login\n",
29
+ "notebook_login()\n",
30
+ "# !huggingface-cli login --token=███"
31
+ ]
32
+ },
33
+ {
34
+ "cell_type": "code",
35
+ "execution_count": null,
36
+ "metadata": {
37
+ "collapsed": false,
38
+ "jupyter": {
39
+ "outputs_hidden": false
40
+ },
41
+ "scrolled": true,
42
+ "trusted": true
43
+ },
44
+ "outputs": [],
45
+ "source": [
46
+ "# workaround for a bug in `datasets` package\n",
47
+ "%pip uninstall -y cudf dask-cuda dask-cudf\n",
48
+ "%pip install -q cudf-cu12 --extra-index-url=https://pypi.nvidia.com\n",
49
+ "%pip install -qU 'datasets[audio]' accelerate transformers jiwer bitsandbytes\n",
50
+ "# install then `import evaluate` throw error on kaggle"
51
+ ]
52
+ },
53
+ {
54
+ "cell_type": "code",
55
+ "execution_count": null,
56
+ "metadata": {
57
+ "collapsed": false,
58
+ "jupyter": {
59
+ "outputs_hidden": false
60
+ },
61
+ "trusted": true
62
+ },
63
+ "outputs": [],
64
+ "source": [
65
+ "import torch\n",
66
+ "from dataclasses import dataclass\n",
67
+ "import datasets as hugDS\n",
68
+ "from transformers import Wav2Vec2BertForCTC, SeamlessM4TFeatureExtractor, Wav2Vec2CTCTokenizer, TrainingArguments, Trainer\n",
69
+ "import jiwer"
70
+ ]
71
+ },
72
+ {
73
+ "cell_type": "code",
74
+ "execution_count": null,
75
+ "metadata": {
76
+ "collapsed": false,
77
+ "jupyter": {
78
+ "outputs_hidden": false
79
+ },
80
+ "trusted": true
81
+ },
82
+ "outputs": [],
83
+ "source": [
84
+ "SAMPLING_RATE = 16_000\n",
85
+ "def load_my_data(mode, **kwargs):\n",
86
+ "\ttmp = hugDS.load_dataset(**kwargs, trust_remote_code=True, streaming=True).cast_column(\"audio\", hugDS.Audio(sampling_rate=SAMPLING_RATE))\n",
87
+ "\tmatch mode:\n",
88
+ "\t\tcase 0:\n",
89
+ "\t\t\treturn tmp\n",
90
+ "\t\tcase 1:\n",
91
+ "\t\t\treturn tmp.select_columns([\"audio\", \"transcription\"])\n",
92
+ "\t\tcase 2:\n",
93
+ "\t\t\treturn tmp.select_columns([\"audio\", \"sentence\"]).rename_column(\"sentence\", \"transcription\")\n",
94
+ "\t\tcase _:\n",
95
+ "\t\t\traise ValueError(\"oh no!\")\n",
96
+ "\n",
97
+ "MY_DATA = hugDS.IterableDatasetDict()\n",
98
+ "\n",
99
+ "MY_DATA[\"train\"] = hugDS.concatenate_datasets([ # total: 1.5M samples\n",
100
+ "\tload_my_data(path=\"google/fleurs\", name=\"vi_vn\", split=\"train\", mode=1), # 3k\n",
101
+ "\tload_my_data(path=\"vivos\", split=\"train\", mode=2), # 11.7k\n",
102
+ "\tload_my_data(path=\"doof-ferb/fpt_fosd\", split=\"train\", mode=0), # 25.9k\n",
103
+ "\tload_my_data(path=\"doof-ferb/infore1_25hours\", split=\"train\", mode=0), # 14.9k\n",
104
+ "\tload_my_data(path=\"doof-ferb/vlsp2020_vinai_100h\", split=\"train\", mode=0), # 56.4k\n",
105
+ "\tload_my_data(path=\"doof-ferb/LSVSC\", split=\"train\", mode=1), # 45k\n",
106
+ "\tload_my_data(path=\"quocanh34/viet_vlsp\", split=\"train\", mode=0), # 171k\n",
107
+ "\tload_my_data(path=\"linhtran92/viet_youtube_asr_corpus_v2\", split=\"train\", mode=1), # 195k\n",
108
+ "\tload_my_data(path=\"doof-ferb/infore2_audiobooks\", split=\"train\", mode=0), # 315k\n",
109
+ "\tload_my_data(path=\"linhtran92/viet_bud500\", split=\"train\", mode=0), # 634k\n",
110
+ "])\n",
111
+ "\n",
112
+ "MY_DATA[\"test\"] = hugDS.concatenate_datasets([ # total: 15k samples\n",
113
+ "\tload_my_data(path=\"mozilla-foundation/common_voice_16_1\", name=\"vi\", split=\"test\", mode=2), # 1.3k\n",
114
+ "\t# remove FLEURS because error when running in batch\n",
115
+ "\tload_my_data(path=\"vivos\", split=\"test\", mode=2), # .7k\n",
116
+ "])"
117
+ ]
118
+ },
119
+ {
120
+ "cell_type": "code",
121
+ "execution_count": null,
122
+ "metadata": {
123
+ "collapsed": false,
124
+ "jupyter": {
125
+ "outputs_hidden": false
126
+ },
127
+ "trusted": true
128
+ },
129
+ "outputs": [],
130
+ "source": [
131
+ "modelID = \"trick4kid/w2v-bert-2.0-vietnamese-CV16.0\"\n",
132
+ "FEATURE_EXTRACTOR = SeamlessM4TFeatureExtractor.from_pretrained(modelID)\n",
133
+ "TOKENIZER = Wav2Vec2CTCTokenizer.from_pretrained(modelID)\n",
134
+ "MODEL = Wav2Vec2BertForCTC.from_pretrained(\n",
135
+ "\tmodelID, ctc_loss_reduction=\"mean\", add_adapter=True, mask_time_prob=0.,\n",
136
+ "\tlayerdrop=0., pad_token_id=TOKENIZER.pad_token_id, vocab_size=len(TOKENIZER)\n",
137
+ ")\n",
138
+ "\n",
139
+ "DUMMY_TOKEN = -100"
140
+ ]
141
+ },
142
+ {
143
+ "cell_type": "code",
144
+ "execution_count": null,
145
+ "metadata": {
146
+ "collapsed": false,
147
+ "jupyter": {
148
+ "outputs_hidden": false
149
+ },
150
+ "trusted": true
151
+ },
152
+ "outputs": [],
153
+ "source": [
154
+ "def prepare_dataset(batch):\n",
155
+ "\taudio = batch[\"audio\"]\n",
156
+ "\tbatch[\"input_features\"] = FEATURE_EXTRACTOR(audio[\"array\"], sampling_rate=SAMPLING_RATE).input_features[0] # compute log-Mel input features\n",
157
+ "\tbatch[\"labels\"] = TOKENIZER(batch[\"transcription\"]).input_ids # encode target text to label ids\n",
158
+ "\treturn batch\n",
159
+ "MY_DATA = MY_DATA.map(prepare_dataset) # no `num_proc` coz streaming"
160
+ ]
161
+ },
162
+ {
163
+ "cell_type": "code",
164
+ "execution_count": null,
165
+ "metadata": {
166
+ "collapsed": false,
167
+ "jupyter": {
168
+ "outputs_hidden": false
169
+ },
170
+ "trusted": true
171
+ },
172
+ "outputs": [],
173
+ "source": [
174
+ "@dataclass\n",
175
+ "class DataCollatorCTCWithPadding:\n",
176
+ "\tdef __call__(self, features):\n",
177
+ "\t\t# split inputs and labels since they have to be of different lengths and need different padding methods\n",
178
+ "\t\tinput_features = [{\"input_features\": feature[\"input_features\"]} for feature in features]\n",
179
+ "\t\tlabel_features = [{\"input_ids\" : feature[\"labels\"] } for feature in features]\n",
180
+ "\n",
181
+ "\t\tbatch = FEATURE_EXTRACTOR.pad(input_features, padding=True, return_tensors=\"pt\")\n",
182
+ "\t\tlabels_batch = TOKENIZER.pad(label_features, padding=True, return_tensors=\"pt\")\n",
183
+ "\t\tlabels = labels_batch[\"input_ids\"].masked_fill(labels_batch.attention_mask.ne(1), DUMMY_TOKEN) # replace padding with -100 to ignore loss correctly\n",
184
+ "\n",
185
+ "\t\tbatch[\"labels\"] = labels\n",
186
+ "\t\treturn batch\n",
187
+ "\n",
188
+ "DATA_COLLATOR = DataCollatorCTCWithPadding()"
189
+ ]
190
+ },
191
+ {
192
+ "cell_type": "code",
193
+ "execution_count": null,
194
+ "metadata": {
195
+ "collapsed": false,
196
+ "jupyter": {
197
+ "outputs_hidden": false
198
+ },
199
+ "trusted": true
200
+ },
201
+ "outputs": [],
202
+ "source": [
203
+ "JIWER_TRANS = jiwer.Compose([ # DO NOT use `jiwer.RemoveEmptyStrings` it can cause rows count mismatch\n",
204
+ "\tjiwer.ToLowerCase(),\n",
205
+ "\tjiwer.RemoveKaldiNonWords(),\n",
206
+ "\tjiwer.RemoveMultipleSpaces(),\n",
207
+ "\tjiwer.Strip(),\n",
208
+ "\tjiwer.RemovePunctuation(),\n",
209
+ "\tjiwer.ReduceToListOfListOfWords(),\n",
210
+ "])\n",
211
+ "\n",
212
+ "def compute_metrics(pred):\n",
213
+ "\tpred_logits, label_ids = pred.predictions, pred.label_ids\n",
214
+ "\tpred_ids = torch.argmax(pred_logits, axis=-1)\n",
215
+ "\tlabel_ids[label_ids == DUMMY_TOKEN] = TOKENIZER.pad_token_id # replace -100 with the pad_token_id\n",
216
+ "\n",
217
+ "\twer = jiwer.wer( # we do not want to group tokens when computing the metrics\n",
218
+ "\t\treference=TOKENIZER.batch_decode(label_ids, group_tokens=False)[0],\n",
219
+ "\t\thypothesis=TOKENIZER.batch_decode(pred_ids)[0],\n",
220
+ "\t\treference_transform=JIWER_TRANS, hypothesis_transform=JIWER_TRANS\n",
221
+ "\t)\n",
222
+ "\treturn {\"wer\": wer}"
223
+ ]
224
+ },
225
+ {
226
+ "cell_type": "code",
227
+ "execution_count": null,
228
+ "metadata": {
229
+ "collapsed": false,
230
+ "jupyter": {
231
+ "outputs_hidden": false
232
+ },
233
+ "trusted": true
234
+ },
235
+ "outputs": [],
236
+ "source": [
237
+ "# mount gdrive using GUI before training\n",
238
+ "%cd '/content/drive/My Drive/coder'\n",
239
+ "\n",
240
+ "# %cd /kaggle/working\n",
241
+ "# !rm -rf ./my-w2v-bert"
242
+ ]
243
+ },
244
+ {
245
+ "cell_type": "code",
246
+ "execution_count": null,
247
+ "metadata": {
248
+ "collapsed": false,
249
+ "jupyter": {
250
+ "outputs_hidden": false
251
+ },
252
+ "trusted": true
253
+ },
254
+ "outputs": [],
255
+ "source": [
256
+ "SAVE_PATH = \"./my-w2v-bert\"\n",
257
+ "BATCH_SIZE = 4 # should be a power of 2\n",
258
+ "# kaggle free P100 train faster than colab free T4\n",
259
+ "# kaggle free T4×2: no speed up but auto double batch size\n",
260
+ "\n",
261
+ "# colab free tier can only run for 8-12h max daily\n",
262
+ "# kaggle free tier can only run for 30h max weekly but max 12h per session\n",
263
+ "\n",
264
+ "has_bf16 = torch.cuda.is_bf16_supported() # GPU Ampere or later\n",
265
+ "\n",
266
+ "TRAINING_ARGS = TrainingArguments(\n",
267
+ "\toutput_dir=SAVE_PATH,\n",
268
+ "\tper_device_train_batch_size=BATCH_SIZE,\n",
269
+ "\tper_device_eval_batch_size=BATCH_SIZE,\n",
270
+ "\tfp16=not has_bf16,\n",
271
+ "\tbf16=has_bf16, tf32=has_bf16,\n",
272
+ "\t# torch_compile=True, # SDPA not support wav2vec yet\n",
273
+ "\treport_to=[\"tensorboard\"],\n",
274
+ "\n",
275
+ "\tmax_steps=1200, # no `num_train_epochs` coz streaming\n",
276
+ "\tlogging_steps=25,\n",
277
+ "\tsave_steps=50,\n",
278
+ "\teval_steps=50,\n",
279
+ "\tevaluation_strategy=\"steps\",\n",
280
+ "\tsave_total_limit=2,\n",
281
+ "\n",
282
+ "\toptim=\"adamw_bnb_8bit\", # 8-bit AdamW optimizer: lower vram usage than default AdamW\n",
283
+ "\tlearning_rate=5e-5,\n",
284
+ "\twarmup_ratio=.05, # keep between 5-15%\n",
285
+ "\tgradient_accumulation_steps=1 if BATCH_SIZE >= 8 else 8 // BATCH_SIZE, # keep effective batch size as min 8 per device\n",
286
+ "\tgradient_checkpointing=True,\n",
287
+ "\tgradient_checkpointing_kwargs={\"use_reentrant\": False},\n",
288
+ "\tload_best_model_at_end=True,\n",
289
+ "\tmetric_for_best_model=\"wer\",\n",
290
+ "\tgreater_is_better=False, # WER is better when lower\n",
291
+ ")\n",
292
+ "\n",
293
+ "TRAINER = Trainer(\n",
294
+ "\targs=TRAINING_ARGS,\n",
295
+ "\tmodel=MODEL,\n",
296
+ "\ttrain_dataset=MY_DATA[\"train\"],\n",
297
+ "\teval_dataset=MY_DATA[\"test\"],\n",
298
+ "\tdata_collator=DATA_COLLATOR,\n",
299
+ "\tcompute_metrics=compute_metrics,\n",
300
+ "\ttokenizer=FEATURE_EXTRACTOR, # not TOKENIZER\n",
301
+ ")"
302
+ ]
303
+ },
304
+ {
305
+ "cell_type": "code",
306
+ "execution_count": null,
307
+ "metadata": {
308
+ "collapsed": false,
309
+ "jupyter": {
310
+ "outputs_hidden": false
311
+ },
312
+ "scrolled": true,
313
+ "trusted": true
314
+ },
315
+ "outputs": [],
316
+ "source": [
317
+ "TRAINER.train() # resume_from_checkpoint=True # only if resume"
318
+ ]
319
+ },
320
+ {
321
+ "cell_type": "code",
322
+ "execution_count": null,
323
+ "metadata": {
324
+ "collapsed": false,
325
+ "jupyter": {
326
+ "outputs_hidden": false
327
+ },
328
+ "trusted": true
329
+ },
330
+ "outputs": [],
331
+ "source": [
332
+ "TRAINER.save_model()\n",
333
+ "!zip -FSr res.zip ./my-w2v-bert"
334
+ ]
335
+ }
336
+ ],
337
+ "metadata": {
338
+ "accelerator": "GPU",
339
+ "colab": {
340
+ "gpuType": "T4",
341
+ "private_outputs": true,
342
+ "provenance": []
343
+ },
344
+ "kaggle": {
345
+ "accelerator": "nvidiaTeslaT4",
346
+ "dataSources": [],
347
+ "isGpuEnabled": true,
348
+ "isInternetEnabled": true,
349
+ "language": "python",
350
+ "sourceType": "notebook"
351
+ },
352
+ "kernelspec": {
353
+ "display_name": "Python 3",
354
+ "language": "python",
355
+ "name": "python3"
356
+ },
357
+ "language_info": {
358
+ "name": "python",
359
+ "version": "3.11.7"
360
+ }
361
+ },
362
+ "nbformat": 4,
363
+ "nbformat_minor": 0
364
+ }