Skip to content

Commit e9a96d5

Browse files
authored
Merge pull request #1004 from Simnol22/sb_tutorial
SpeechBrain Tutorial
2 parents f6ba53b + 0becddb commit e9a96d5

5 files changed

Lines changed: 990 additions & 0 deletions

File tree

docs/src/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
auto_tutorials/code_4_parallelism
3838
tutorials/cluster
3939
tutorials/pytorch_a2c_ppo
40+
tutorials/speechbrain_tutorial
4041

4142
.. toctree::
4243
:caption: Plugins
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
********************
2+
SpeechBrain
3+
********************
4+
5+
In this short tutorial, we're going to demonstrate how Oríon can be integrated to a `SpeechBrain
6+
<https://speechbrain.github.io/>`_ speech recognition model.
7+
The files mentioned in this tutorial are available in the `Oríon
8+
<https://github.com/Epistimio/orion/tree/develop/examples>`_ repository.
9+
10+
Installation and setup
11+
======================
12+
13+
Make sure Oríon is installed (:doc:`/install/core`).
14+
15+
Then install SpeechBrain using ``$ pip install speechbrain``
16+
17+
Code used in this tutorial
18+
==========================
19+
20+
In this tutorial, we are going to use some code from the `SpeechBrain
21+
<https://github.com/speechbrain/speechbrain>` repository. More specifically, a speech recognition
22+
template made as an example. We will repurpose this example to adapt it for Oríon. The template
23+
used for creating this tutorial can be found `here
24+
<https://github.com/speechbrain/speechbrain/tree/develop/templates/speech_recognition/ASR>`.
25+
You can also directly see the code modified for this example here :
26+
``examples/speechbrain_tutorial``.
27+
28+
We used the ``train.py`` file, but created a ``main.py``, with the ``main`` function,
29+
which we slightly modified for optimizing the hyperparamers with Oríon.
30+
31+
Adapting the Speechbrain for Oríon
32+
==================================
33+
34+
The Adaptation for using Oríon is quite simple.
35+
36+
1) We first need to import ``orion.report_objective()`` into the project.
37+
38+
.. code-block:: python
39+
40+
from orion.client import report_objective
41+
42+
2) We then need to change the evaluation from the training data to the validation data.
43+
The evaluation method should look like this. It returns the validation loss.
44+
45+
.. literalinclude:: /../../examples/speechbrain_tutorial/main.py
46+
:language: python
47+
:lines: 75-80
48+
49+
3) Finally, we call ``report_objective`` at the end to return the final objective value,
50+
the validation loss, to Oríon.
51+
52+
.. code-block:: python
53+
54+
report_objective(valid_stats)
55+
56+
The code is now adapted and ready to be used with Oríon.
57+
58+
Execution
59+
=========
60+
61+
We are now going to call the ``orion hunt`` command.
62+
Notice that we still need to give the ``train.yaml``
63+
file to speechbrain, since the general configuration is in there. However, we are going to specify
64+
the hyperparameters that we want to optimize in the command line,
65+
which will automatically overrides the ones set in the ``train.yaml``. When an argument
66+
is defined both in the yaml configuration file and in command line, SpeechBrain
67+
gives precedence to values provided in command line. Thus, defining the hyperparamers through
68+
the command line for Oríon allows overriding the values in ``train.yaml`` in SpeechBrain.
69+
70+
.. code-block:: bash
71+
72+
orion hunt \
73+
--enable-evc -n <experiment_name> \
74+
python main.py train.yaml \
75+
--lr~'loguniform(0.05, 0.2)' \
76+
--ctc_weight~'loguniform(0.25, 0.75)' \
77+
--label_smoothing~'loguniform(1e-10, 10e-5)' \
78+
--coverage_penalty~'loguniform(1.0, 2.0)' \
79+
--temperature~'loguniform(1.0, 1.5)' \
80+
--temperature_lm~'loguniform(1.0, 1.5)'
81+
82+
Results
83+
=======
84+
85+
When an experiment reaches its termination criterion, basically ``max-trials``,
86+
you can see the results using the following command:
87+
88+
.. code-block:: bash
89+
90+
$ orion info -n <experiment_name>
91+
92+
Which outputs the following statistics:
93+
94+
.. code-block:: bash
95+
96+
Stats
97+
=====
98+
completed: True
99+
trials completed: 209
100+
best trial:
101+
id: 8675cfcfba768243e1ed1ac7825c69b6
102+
evaluation: 0.13801406680803444
103+
params:
104+
/coverage_penalty: 1.396
105+
/ctc_weight: 0.389
106+
/label_smoothing: 2.044e-10
107+
/lr: 0.06462
108+
/temperature: 1.175
109+
/temperature_lm: 1.087
110+
start time: 2022-09-29 14:37:41.048314
111+
finish time: 2022-09-30 20:08:07.384765
112+
duration: 1 day, 5:30:26.336451
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import logging
2+
import sys
3+
4+
import speechbrain as sb
5+
import torch
6+
from hyperpyyaml import load_hyperpyyaml
7+
from mini_librispeech_prepare import prepare_mini_librispeech
8+
from speechbrain.utils.distributed import run_on_main
9+
from train import ASR, dataio_prepare
10+
11+
from orion.client import report_objective
12+
13+
logger = logging.getLogger(__name__)
14+
15+
if __name__ == "__main__":
16+
hparams_file, run_opts, overrides = sb.parse_arguments(sys.argv[1:])
17+
18+
# Initialize ddp (useful only for multi-GPU DDP training)
19+
sb.utils.distributed.ddp_init_group(run_opts)
20+
21+
# Load hyperparameters file with command-line overrides
22+
with open(hparams_file) as fin:
23+
hparams = load_hyperpyyaml(fin, overrides)
24+
25+
# Create experiment directory
26+
sb.create_experiment_directory(
27+
experiment_directory=hparams["output_folder"],
28+
hyperparams_to_save=hparams_file,
29+
overrides=overrides,
30+
)
31+
32+
# Data preparation, to be run on only one process.
33+
sb.utils.distributed.run_on_main(
34+
prepare_mini_librispeech,
35+
kwargs={
36+
"data_folder": hparams["data_folder"],
37+
"save_json_train": hparams["train_annotation"],
38+
"save_json_valid": hparams["valid_annotation"],
39+
"save_json_test": hparams["test_annotation"],
40+
},
41+
)
42+
43+
# We can now directly create the datasets for training, valid, and test
44+
datasets = dataio_prepare(hparams)
45+
46+
# In this case, pre-training is essential because mini-librispeech is not
47+
# big enough to train an end-to-end model from scratch. With bigger dataset
48+
# you can train from scratch and avoid this step.
49+
# We download the pretrained LM from HuggingFace (or elsewhere depending on
50+
# the path given in the YAML file). The tokenizer is loaded at the same time.
51+
run_on_main(hparams["pretrainer"].collect_files)
52+
hparams["pretrainer"].load_collected(device=torch.device("cpu"))
53+
54+
# Trainer initialization
55+
asr_brain = ASR(
56+
modules=hparams["modules"],
57+
opt_class=hparams["opt_class"],
58+
hparams=hparams,
59+
run_opts=run_opts,
60+
checkpointer=hparams["checkpointer"],
61+
)
62+
63+
# The `fit()` method iterates the training loop, calling the methods
64+
# necessary to update the parameters of the model. Since all objects
65+
# with changing state are managed by the Checkpointer, training can be
66+
# stopped at any point, and will be resumed on next call.
67+
asr_brain.fit(
68+
asr_brain.hparams.epoch_counter,
69+
datasets["train"],
70+
datasets["valid"],
71+
train_loader_kwargs=hparams["train_dataloader_opts"],
72+
valid_loader_kwargs=hparams["valid_dataloader_opts"],
73+
)
74+
75+
# Load best checkpoint for evaluation
76+
valid_stats = asr_brain.evaluate(
77+
test_set=datasets["valid"],
78+
min_key="WER",
79+
test_loader_kwargs=hparams["valid_dataloader_opts"],
80+
)
81+
82+
report_objective(valid_stats)

0 commit comments

Comments
 (0)