0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

COEIROINKエンジンをDocker+CLIで起動して音声合成APIを叩いてみた

Posted at

概要

お疲れさまです、ツーナです!
最近、個人利用のAIと会話できるアプリを作っているのですが、
その過程で「つくよみちゃん」の声を使いたいなと思い、
調べたところ COEIROINK に辿り着きました。

COEIROINKのダウンロードページ
https://coeiroink.com/download

当初は、以下のエンジンリポジトリがあることを知り、
これを利用して起動する予定でした。
https://github.com/shirowanisan/voicevox_engine

しかしながら、pyopenjtalkのビルド周りや依存関係に
関するエラー修正難航してしまい、一旦断念しました。

そこで一旦GUIの方がどうなっているのか見てみようかなと
COEIROINKエディタ版の 中身をざっと見ると
engineというバイナリがあり、
これを起動することでAPIサーバが立ち上がる
仕様になっていました。

なので、これをうまく使えばAWSやGCP(FargateやCloud Run)
で利用するなどにも応用できそうです。

今回は、

  • COEIROINKのLinux版をDocker上で動かす
  • CLIでAPIサーバを立ち上げる
  • PostmanでAPIを叩き、音声を合成する

という流れをまとめました!


結論

最終的に出来上がったDockerfileは以下に
なりますので、結論だけ欲しい方は以下よりお願いします。
https://github.com/devtoona/coe-cloud-run


ディレクトリ構成

プロジェクトルートに以下を配置しています。

.
├── Dockerfile
├── start.sh
└── COEIROINK_LINUX_CPU_v.2.11.2/
    ├── engine/
    │   └── engine (実行バイナリ)
    └── 他フォルダ・ファイル

Dockerfileの作成

Dockerfileを最小構成に仕上げるため
engineが依存している共有ライブラリを確認してみました。

ldd engine/engine

出力は以下のとおりでした。

libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fffff7b8000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fffff79c000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fffff797000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fffff56e000)
/lib64/ld-linux-x86-64.so.2 (0x00007ffffffc4000)

で、ライブラリ名とubuntuイメージに含まれているかを確認したところ、
全て標準で含まれているのでCOEIROINKエンジンを動かすのに追加で
インストールは必要なさそうです。

ライブラリ名 内容 Ubuntuに含まれるか
libdl.so.2 動的リンク用ライブラリ ✅ 標準(glibc)
libz.so.1 圧縮・解凍ライブラリ(zlib) ✅ 標準
libpthread.so.0 POSIXスレッドライブラリ ✅ 標準(glibc)
libc.so.6 C言語標準ライブラリ ✅ 標準(glibc)
ld-linux-x86-64.so.2 ELFローダ(実行時リンクローダ) ✅ 標準(glibc)

なので、

  1. COEIROINKのダウンロード
  2. ダウンロードしたCOEIROINKをDocker内にコピー
  3. Ubuntu 22.04ベースのDockerfileを用意し、engine を実行

という手順でAPIが使える!と思いきや、APIに接続できない という
壁にぶち当たりました。


接続できなかった原因

127.0.0.1 にしかバインドされていない

./engine/engine

このコマンドでAPIサーバは 127.0.0.1:50032 にバインドされます。
そのため、Dockerで以下のようにポートを開けても:

docker run -p 50032:50032 ...

ホストからはアクセスできません。

理由は「127.0.0.1」はコンテナ内のローカルを指しており、
ホスト側から見たときにそのポートは見えないからです。


解決策

socat でポートフォワーディング

socat はネットワークプロキシのように動きます。

socat TCP-LISTEN:50033,fork TCP:127.0.0.1:50032

このコマンドにより:

  • 0.0.0.0:50033 で受けた通信を
  • 127.0.0.1:50032 に中継してくれます

つまり、ホストからは localhost:50033 にアクセスするだけで
Docker内の 127.0.0.1:50032 に繋がる、という仕組みになります。

Dockerでは -p 50033:50033 でポートを開けておけばOK!


最終的に出来上がったDockerfile

FROM ubuntu:22.04

# 非対話モードにしておく
ENV DEBIAN_FRONTEND=noninteractive
# ポート中継に必要なsocatをインストール
RUN apt update && apt install -y \
    socat \
    && apt clean && rm -rf /var/lib/apt/lists/*

ARG ENGINE_NAME="COEIROINK_LINUX_CPU_v.2.11.2"
COPY ./${ENGINE_NAME} /opt/${ENGINE_NAME}
COPY ./start.sh /opt/${ENGINE_NAME}/start.sh
WORKDIR /opt/${ENGINE_NAME}

# バイナリやシェルスクリプトに実行権限を付与
RUN chmod +x ./engine/engine
RUN chmod +x ./start.sh
CMD ["./start.sh"]
start.sh
#!/bin/bash

# バイナリの起動をログファイルを使って監視
./engine/engine > engine.log 2>&1 &

# "Uvicorn running" が出るまで(エンジン起動まで)ループで待機
while ! grep -q "Uvicorn running on" engine.log; do
    sleep 0.2
done

color="\033[1;32m"
color_default="\033[0m"


# エンジン起動後にカスタムメッセージを表示
echo -e "${color}INFO${color_default}    running on http://127.0.0.1:50033 (Press CTRL+C to quit)"

# socatでポート中継
socat TCP-LISTEN:50033,fork TCP:127.0.0.1:50032


ビルドと実行

以下に示すコマンドでビルドと実行をします。
私の環境では、M1macを利用していたため、platformを指定しています。

# ビルド
docker buildx build --platform linux/amd64 --load -t coeiroink-engine-x86

# 実行
docker run -p 50033:50033 -it --platform linux/amd64 coeiroink-engine-x86.

補足

platformをlinux/amd64に指定しないと

rosetta error: failed to open elf at /lib64/ld-linux-x86-64.so.2

というエラーが出ます。
これは、Apple Silicon(M1/M2などのarm64)Mac上で、linux/amd64 向けのバイナリを実行しようとして失敗するためです。
(言い換えれば、COEIROINKを実行にはlinux/amd64である必要があるということです。)


APIを呼び出し音声合成できるかの確認

上記が終わったら、127.0.0.1:50033にアクセスして
APIを呼びだせると思います。

APIの仕様は公式サイト(https://coeiroink.com/help/002)
が参考になると思います。

私の環境では、APIドキュメントを参考にPostmanを使って
話者リストを取得し、その値を使いつつ
/v1/synthesisを呼び出すと音声合成できました。

そのときの設定値は以下ですが、色々変えてみるのも面白いと思います。

{
  "volumeScale": 1.0,
  "pitchScale": 0.1,
  "intonationScale": 1.0,
  "prePhonemeLength": 1.0,
  "postPhonemeLength":1.0,
  "outputSamplingRate": 48000,
  "speakerUuid": "3c37646f-3881-5374-2a83-149267990abc",
  "styleId": 6,
  "text": "こんにちは!つくよみちゃんです!",
  "speedScale": 1.0
}

まとめ

COEIROINKのランタイムAPIを、Docker + CLI + Postmanで
動かすことに成功しました!

調べてもGUIで立ち上げるみたいな記事ばかりでCLIで起動している
方法がほとんどなかったので、同じように
「DockerからAPI叩きたいけどアクセスできねぇ!」
と悩んでいる方の役に立てば嬉しいです!


0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?