VOICEVOX 0.2.0 をUbuntu 21.04環境へインストールする

要約：voicevox_engine バージョン0.2.0 をGitHubからインストールするには、事前に依存パッケージをAPTでインストールしておく

追記（2021/09/09）
合わせて読みたい：

https://qiita.com/isnot_naoto/items/0794c8ae566f67ac59c6

追記（2022/02/20）

現在ではLinux向け公式ビルドが提供されています。
公式サイトよりダウンロードが可能です。
https://voicevox.hiroshiba.jp/

-----

## この記事の概要

[VOICEVOX](https://voicevox.hiroshiba.jp/)は、無料かつ商用利用も可能な、日本語向け音声合成ソフトウェアです。
現在、Windows向けのバイナリ・パッケージ（zip）とともに、GitHubでオープンソース版が公開されています。

- https://github.com/Hiroshiba/voicevox
- https://github.com/Hiroshiba/voicevox_engine

リポジトリで構成要素を見ていくと、基本的にOSの種類に対する依存はほぼなく、メジャーなOSであれば動作可能だろうと思われました。
そこで、Ubuntu 21.04 にインストールしていくこととします。

## 動作デモ

 https://twitter.com/isnot49662340/status/1422957863660490759

Voice: ずんだもん
Voice: 四国めたん

## 事前の準備と、参照した事例
Windows以外の環境でのインストールおよび利用については、先行する事例を参考にしました。

[オープンソース日本語 TextToSpeech ソフトウェア VOICEVOX の紹介と Tips](https://bbs.avalontech.jp/t/topic/1002/3#post_3)

特に、voicevox_engineのインストールについては、以下の引用で示すように、事前にAPTパッケージの導入を済ませておく必要がありました。

> ```$ sudo apt install libatlas-base-dev cmake ninja-build```[^1]

[^1]: [オープンソース日本語 TextToSpeech ソフトウェア VOICEVOX の紹介と Tips](https://bbs.avalontech.jp/t/topic/1002/3#post_3) より引用

他にも、__build-essential__ といったパッケージが必要になるかもしれません。
もちろん、git、pip、Python3、(venv[^2])、Node.js、npm（またはyarn）、（nvm）が必要です。
[^2]: Python仮想環境 Python3.9-venv 必ずしも必須ではない

## VOICEVOXの内部構成を見ていく

VOICEVOXは、内部的に2つのパートで構成されています。

#### voicevox_engine [音声合成エンジン]
- Python3でローカルにHTTPサーバを立てて、バックエンドとして機能する
    - 127.0.0.1 50021/tcp
- [OpenAPI](https://qiita.com/tags/openapi) 3.0 準拠 FastAPI, uvicorn
    - APIリファレンス http://localhost:50021/docs または http://localhost:50021/redoc
    - OpenAPI Specification http://localhost:50021/openapi.json
- Windopws版は、nuitkaでパッケージ化されている
- リポジトリには一部実装が欠如しており、動作させることができない[^3]
    - 不足：each_cpp_forwarder
- 上記の不足を回避する方法
    - 現状ではWindows版パッケージの中からビルド＆パッケージ化済のバイナリを取り出して、Wineを使って実行することができる
    - ```$ wine64 run.exe```

[^3]: [2021/08/06 23:09現在エラーが出ます](https://github.com/Hiroshiba/voicevox_engine/blob/master/README.md#%E5%AE%9F%E8%A1%8C)


#### voicevox [GUI]
- Electron ＋ Vue.js で構成されている
- Windows版はElectronでパッケージ化されている
- Ubuntu等で利用する際は、必ずしもパッケージ化は必要ない模様
    - ```$ npm run electron:serve```
- 実行順序に注意。必ず先にrun.exeを動かして（HTTPサーバを立てて）から、上記の通りに起動する

## インストール作業実施例

では、冒頭であげた2つのGitHubリポジトリから、インストールする流れを見ていきます。
予め、Windows版パッケージを取得しておいてください。リンクは冒頭のVOICEVOX公式サイトを参照してください[^4]。

[^4]: 時期によって配布サーバが変更されることがあります。いまのところ4箇所の変遷がありました😅

```bash
$ unzip VOICEVOX-0.2.0-win.zip
$ cd VOICEVOX
$ wine64 run.exe
```

- 動作確認するには、ブラウザで http://localhost:50021/docs を開く
- 「FastAPI〜」で始まるコンテンツが見えていればOK

run.exeを実行したままで、別のターミナルを開く

```bash
$ git clone https://github.com/Hiroshiba/voicevox
$ cd voicevox
$ cp .env.production .env
$ sed -i -e 's/run\.exe/wine64 run\.exe/' .env # 意味ないかもしれない
$ npm ci
$ npm run electron:serve
```

- VOICEVOX本体とも言える、メインのウィンドウ（GUI）が起動する
- 「音声合成エンジンエラー」ダイアログが表示されます（場合がある）が、OKボタンで閉じましょう
- 画面内に開発者ツールが開く場合があるが、右上？（参考画像の赤丸）のxで閉じてOK

![Screenshot from 2021-08-07 18-34-27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391342/30a89044-0dd7-235e-e4b6-3596b57533e9.png)

![2021-08-07_18-40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391342/f6a465d2-615f-c5af-b68f-5a65216e312b.png)

ここまでで、インストールの流れは完了です。
VOICEVOXを楽しみましょう。

#### 以下（現時点では）不要

wineを使ってrun.exeを実行する場合は、以下不要。
別のターミナルを開く

```bash
$ sudo apt install libatlas-base-dev cmake ninja-build
$ git clone https://github.com/Hiroshiba/voicevox_engine
$ cd voicevox_engine
$ pip install -r requirements.txt -r requirements-dev.txt
$ python run.py  # 2021/08/06 23:09現在エラーが出ます
```

今後の展望として、voicevox_engine の完全体リポジトリが公開され、Windows版パッケージのダウンロードや、wineを使わずに済むようになることを、個人的に期待しています。

<details><summary>付録：voicevox_engine インストール実行時のターミナル出力内容</summary><div>

```terminal
Script started on 2021-08-07 15:51:37+09:00
$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=21.04
DISTRIB_CODENAME=hirsute
DISTRIB_DESCRIPTION="Ubuntu 21.04"
$ python --version
Python 3.9.5
$ pip --version
pip 20.3.4 from /home/naoto/repos/voicevox_engine_install/lib/python3.9/site-packages/pip (python 3.9)
$ pip list
Package       Version
------------- -------
pip           20.3.4
pkg-resources 0.0.0
setuptools    44.1.1
$ cat VERSION.txt 
0.2.0
$ cat requirements.txt 
numpy
fastapi
python-multipart
uvicorn
aiofiles
soundfile
git+https://github.com/r9y9/pyopenjtalk
git+https://github.com/Hiroshiba/python-romkan
$ cat requirements-dev.txt 
cython
nuitka
pip-licenses
 
$ pip install -r requirements-dev.txt -r requirements.txt 
Collecting git+https://github.com/r9y9/pyopenjtalk (from -r requirements.txt (line 7))
  Cloning https://github.com/r9y9/pyopenjtalk to /tmp/pip-req-build-h9ikrbdj
  Running command git clone -q https://github.com/r9y9/pyopenjtalk /tmp/pip-req-build-h9ikrbdj
  Running command git submodule update --init --recursive -q
  Installing build dependencies ... - \ | / - done
  Getting requirements to build wheel ... - \ | / - \ | / - \ | / - \ | / - \ done
    Preparing wheel metadata ... - done
Collecting git+https://github.com/Hiroshiba/python-romkan (from -r requirements.txt (line 8))
  Cloning https://github.com/Hiroshiba/python-romkan to /tmp/pip-req-build-ftlobari
  Running command git clone -q https://github.com/Hiroshiba/python-romkan /tmp/pip-req-build-ftlobari
Collecting cython
  Using cached Cython-0.29.24-cp39-cp39-manylinux1_x86_64.whl (1.9 MB)
Collecting nuitka
  Using cached Nuitka-0.6.16.2-py3-none-any.whl
Collecting pip-licenses
  Using cached pip_licenses-3.5.1-py3-none-any.whl (17 kB)
Collecting numpy
  Using cached numpy-1.21.1-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (15.8 MB)
Collecting fastapi
  Using cached fastapi-0.68.0-py3-none-any.whl (52 kB)
Collecting python-multipart
  Using cached python_multipart-0.0.5-py3-none-any.whl
Collecting uvicorn
  Using cached uvicorn-0.14.0-py3-none-any.whl (50 kB)
Collecting aiofiles
  Using cached aiofiles-0.7.0-py3-none-any.whl (13 kB)
Collecting soundfile
  Using cached SoundFile-0.10.3.post1-py2.py3-none-any.whl (21 kB)
Collecting six
  Using cached six-1.16.0-py2.py3-none-any.whl (11 kB)
Collecting pydantic!=1.7,!=1.7.1,!=1.7.2,!=1.7.3,!=1.8,!=1.8.1,<2.0.0,>=1.6.2
  Using cached pydantic-1.8.2-cp39-cp39-manylinux2014_x86_64.whl (11.3 MB)
Collecting starlette==0.14.2
  Using cached starlette-0.14.2-py3-none-any.whl (60 kB)
Collecting typing-extensions>=3.7.4.3
  Using cached typing_extensions-3.10.0.0-py3-none-any.whl (26 kB)
Collecting PTable
  Using cached PTable-0.9.2-py3-none-any.whl
Collecting cffi>=1.0
  Using cached cffi-1.14.6-cp39-cp39-manylinux1_x86_64.whl (405 kB)
Collecting pycparser
  Using cached pycparser-2.20-py2.py3-none-any.whl (112 kB)
Collecting click>=7.*
  Using cached click-8.0.1-py3-none-any.whl (97 kB)
Collecting asgiref>=3.3.4
  Using cached asgiref-3.4.1-py3-none-any.whl (25 kB)
Collecting h11>=0.8
  Using cached h11-0.12.0-py3-none-any.whl (54 kB)
Using legacy 'setup.py install' for romkan, since package 'wheel' is not installed.
Building wheels for collected packages: pyopenjtalk
  Building wheel for pyopenjtalk (PEP 517) ... - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / done
  Created wheel for pyopenjtalk: filename=pyopenjtalk-0.1.3a0+59a33c0-cp39-cp39-linux_x86_64.whl size=5270444 sha256=ca5ad6c8d31c1a31bd08c5b10b4281095dcec9773a0412f048d764acd91bdd9d
  Stored in directory: /tmp/pip-ephem-wheel-cache-lx5mww3a/wheels/9c/cd/b6/98207756c27430856070b761a6d07c154c22c644ab213e4f89
Successfully built pyopenjtalk
Installing collected packages: typing-extensions, pycparser, starlette, six, pydantic, PTable, numpy, h11, cython, click, cffi, asgiref, uvicorn, soundfile, romkan, python-multipart, pyopenjtalk, pip-licenses, nuitka, fastapi, aiofiles
    Running setup.py install for romkan ... - done
Successfully installed PTable-0.9.2 aiofiles-0.7.0 asgiref-3.4.1 cffi-1.14.6 click-8.0.1 cython-0.29.24 fastapi-0.68.0 h11-0.12.0 nuitka-0.6.16.2 numpy-1.21.1 pip-licenses-3.5.1 pycparser-2.20 pydantic-1.8.2 pyopenjtalk-0.1.3a0+59a33c0 python-multipart-0.0.5 romkan-0.2.1 six-1.16.0 soundfile-0.10.3.post1 starlette-0.14.2 typing-extensions-3.10.0.0 uvicorn-0.14.0
$ pip show pyopenjtalk
Name: pyopenjtalk
Version: 0.1.3a0+59a33c0
Summary: A python wrapper for OpenJTalk
Home-page: https://github.com/r9y9/pyopenjtalk
Author: Ryuichi Yamamoto
Author-email: zryuichi@gmail.com
License: MIT
Location: /home/naoto/repos/voicevox_engine_install/lib/python3.9/site-packages
Requires: six, cython, numpy
Required-by: 
$ python run.py 
Traceback (most recent call last):
  File "/home/naoto/repos/voicevox_engine_install/voicevox_engine/run.py", line 6, in <module>
    import each_cpp_forwarder
ModuleNotFoundError: No module named 'each_cpp_forwarder'
```

</div></details>

## この記事での実行環境

Ubuntu Linux 21.04
Python 3.9.5
pip 20.3.4
Node.js 14.17.4
npm 7.20.3
wine64 wine-5.0.3 (Ubuntu 5.0.3-3)
voicevox 0.2.0 (VOICEVOX-0.2.0-win.zip, GitHub)

## おまけ：なぜUbuntuで？

私の場合で言うならば、それはUbuntuが常用のデスクトップ環境であり、開発環境だからです。

ところで、日本語による音声合成を使った動画の投稿は、niconicoやYouTubeをはじめとして、よく見かけると思います。いわゆる、ゆっくり実況やボイロ動画です。
それらの動画を制作する環境としては、間違いなくWindowsがデファクトであると思います。

一方でVOICEVOXでは、その技術的基盤として、PythonやElectronを採用しています。
私にとって、OS依存の（ほぼ）ないソフトウェアであったことが、エポックメイキングであると感じました。
つまり、それまでのエコシステムの枠を超える、新しい領域への展望が、現実的に視野に入ってくるということです。

より具体的には、作者様も言及していますが、例えば動作環境をDockerに乗せることで、クラウド基盤（AWS、GCP、Azure、オンプレも含めて）で動作させることも、容易になるだろうということです。
デスクトップのスタンドアロンで利用するにはまず関係のないことですが、既存のエコシステムの中にはなかなかなかった、大きな強みであると思います。

音声合成をサービスとして、周辺の多種多様なプロダクトと連携・発展させるという妄想が捗ります。そのためには、安定して開発を進めたり、運用をスケールさせる手段として、クラウド対応（コンテナ化）があります。

そういったことでなくとも、私にとって、HTTPでAPIが見える／使えることが、基本的な価値と感じています。
あとは、好きな言語（たとえばJavaScript Node.js）で、いろいろ弄くりたくなってくるというわけです。

作者のヒホさんには、たくさんのお礼が言いたい、です。ありがとう！

VOICEVOX © 2021 [Hiroshiba Kazuyuki](https://twitter.com/hiho_karuta)