XavierでOpenNMTを動かしてみた。

趣味で機械学習のお勉強である。
動作環境はJetson Xavier AGXという組み込み端末を利用した。
OpenNMTは最新版を動かした方がいいのだろうか？と考えて今日も無駄な努力をしてしまった。
備忘録を残しておく。

## 先に grpc install
grpcはパッケージがないらしくビルドに時間がかかる。
pipだとマルチコアを全て使ってビルドしなかったのでコマンドを叩くことにした。

```bash
git clone https://github.com/grpc/grpc -b v1.62.0 --depth 1
cd grpc
git submodule update --init
python -m venv env
source env/bin/activate
pip install -r requirements.txt
python setup.py bdist_wheele
```

## OpenNMT-py 3.3.0 インストール

少し古いバージョンであればpipで動かすことができた。
`OpenNMT`をインストールすると`pytorch==2.0.1`が導入されるが、上書きで[NVIDIAコミュニティが配布](https://forums.developer.nvidia.com/t/pytorch-for-jetson/72048)しているパッケージをインストールした。

```bash
pip install OpenNMT-py==3.3.0
pip install --no-cache https://developer.download.nvidia.cn/compute/redist/jp/v512/pytorch/torch-2.1.0a0+41361538.nv23.06-cp38-cp38-linux_aarch64.whl
```
※ パッケージの`jp/512` は JetPack v5.1.2の略。

## OpenNMT-py 3.4.3 インストール

現行最新版(v3.4.3)をインストールすると`torch.distributed`でエラーとなる。

[PyTorch for Jetson](https://forums.developer.nvidia.com/t/pytorch-for-jetson/72048)を参考に`pytorch==2.1.2`のビルドを行った。

```
Traceback (most recent call last):
  File "/home/o2/work/opennmt_test/env/bin/onmt_train", line 8, in <module>
    sys.exit(main())
  File "/home/o2/work/opennmt_test/env/lib/python3.8/site-packages/onmt/bin/train.py", line 67, in main
    train(opt)
  File "/home/o2/work/opennmt_test/env/lib/python3.8/site-packages/onmt/bin/train.py", line 52, in train
    train_process(opt, device_id=0)
  File "/home/o2/work/opennmt_test/env/lib/python3.8/site-packages/onmt/train_single.py", line 237, in main
    trainer.train(
  File "/home/o2/work/opennmt_test/env/lib/python3.8/site-packages/onmt/trainer.py", line 354, in train
    self.model_saver.save(step, moving_average=self.moving_average)
  File "/home/o2/work/opennmt_test/env/lib/python3.8/site-packages/onmt/models/model_saver.py", line 136, in save
    ckpt_path, _ = self._save(step, save_model)
  File "/home/o2/work/opennmt_test/env/lib/python3.8/site-packages/onmt/models/model_saver.py", line 204, in _save
    if torch.distributed.is_initialized():
AttributeError: module 'torch.distributed' has no attribute 'is_initialized'
```

## cmake インストール

パッケージをダウンロードしてPATHを通す。ビルドは不要である。
```
$ wget https://github.com/Kitware/CMake/releases/download/v3.28.2/cmake-3.28.2-linux-aarch64.tar.gz
$ tar xvzf cmake-3.28.2-linux-aarch64.tar.gz
$ export PATH=$HOME/lib/cmake-3.28.2-linux-aarch64/bin:$PATH
```

## pytorch 2.1.2 ビルド

`AttributeError: module 'torch.distributed' has no attribute 'is_initialized'`を回避するために`USE_DISTRIBUTED=1`にする必要がある。

Xavierの場合、`TORCH_CUDA_ARCH_LIST="7.2;8.7"`を指定。Jetsonは`"5.3;6.2;7.2"`になる。
ビルドは非常に時間がかかる。半日(12時間)は待つ必要がある。

```

$ sudo apt-get install python-pip cmake libopenblas-dev libopenmpi-dev 

$ export USE_NCCL=1
$ export USE_DISTRIBUTED=1
$ export USE_QNNPACK=0
$ export USE_PYTORCH_QNNPACK=0
$ export TORCH_CUDA_ARCH_LIST="7.2;8.7"

$ export PYTORCH_BUILD_VERSION=2.1.2
$ export PYTORCH_BUILD_NUMBER=1
$ export USE_CUDA=1
$ export USE_CUDNN=1

$ git clone --recursive --branch v$PYTORCH_BUILD_VERSION http://github.com/pytorch/pytorch --depth 1
$ cd pytorch

$ python3 -m venv env
$ source env/bin/activate

$ pip install -U pip
$ sudo pip install -U setuptools
$ sudo pip install -r requirements.txt
$ pip install scikit-build
$ pip install ninja

$ python setup.py bdist_wheel
```

## OpenNMT トレーニング

こちらの「OpenNMT-py によるニューラル機械翻訳演習」を参考にトレーニングを実施した。

https://x.com/mamoruk/status/1399934768985243652?s=20


一部情報が古いらしく`--replace_unk`のパラメータを指定している箇所は削除し、`-gpt=0`をパラメータに追加することで全て動作することが確認できた。

また、設定のyamlに`tensorboard`を追記してグラフでも確認できた。
```bash
%%bash
cat > tanaka-enja.yaml << __EOF__
# 前処理したデータの出力先の設定
save_data: ./tanaka
src_vocab: ./tanaka/vocab.src
tgt_vocab: ./tanaka/vocab.tgt
overwrite: True
tensorboard: true
tensorboard_log_dir: logs

# 学習に必要なデータが置いてある置き場所
data:
        corpus_1:
                path_src: small_parallel_enja/train.en
                path_tgt: small_parallel_enja/train.ja
        valid:
                path_src: small_parallel_enja/dev.en
                path_tgt: small_parallel_enja/dev.ja

# ここから学習時の設定
world_size: 1
gpu_ranks: [0]

save_model: ./tanaka/run/model
save_checkpoint_steps: 500
train_steps: 20000
valid_steps: 500
__EOF__
```

```bash
$ tensorboard --logdir=logs
Serving TensorBoard on localhost; to expose to the network, use a proxy or pass --bind_all
TensorBoard 2.14.0 at http://localhost:6006/ (Press CTRL+C to quit)
```

ようやく動く環境ができた。
組み込み系の端末はパッケージが用意されていないこともあり、無駄に時間がかかるのでおすすめはできない。