plgarc/wip/llama.cppでpkgsrcのBLASサポートを探る

この記事は、NetBSD Advent Calendar 2024の13日目の記事です。

llama.cppを使ってみる

以前に、NetBSD/amd64でllama.cppを使ってみるという記事でllama.cppを使ってみていました。 あれから、llama.cppはバージョンアップを繰り返し、様々なLLMも公開されました。 それほど頻繁ではないものの、私もllama.cppを使ってみています。 今回はb4333にアップデートするに当たって気付いたpkgsrcでのBLASサポートについて書きたいと思います。

シングルスレッドでしか動いていない

簡単ではない、例えば数百字以上の出力を求めるプロンプトを与えると、何も返事か返って来ない事象が発生していました。 また、以前も書いたようにプロンプトのテンプレートの問題なのかと思っていたのですが、とても長く待つと、ちゃんと返事が返って来ました。 そこで、処理中にtop(1)コマンドで状況を確認すると、1CPUしか使っていませんでした。 実行しているラップトップには8コア16スレッドを内蔵したCPUが搭載されています。 ログを見てみると、8スレッド以上は使ってくれそうです。 そこで、どのようになっているのか調べてみることにしました。

BLASバックエンドのソースコードを確認する

BLASサポートは、b4333だと、ggml/src/ggml-blasというディレクトリー内に格納されているようです。 このディレクトリー内のファイルを読んでも、マルチコア/マルチスレッドサポートの記述はなさそうです。 となると、BLASライブラリーがマルチコア/マルチスレッドサポートをしていると考えるのが適切そうです。

pkgsrcでのBLASサポート

pkgsrcには、いくつもBLASに相当するライブラリーのパッケージがあります。以下に挙げてみます。

  • math/blas
  • math/blas64
  • math/openblas
  • math/openblas64
  • math/openblas_openmp
  • math/openblas64_openmp
  • math/openblas_pthread
  • math/openblas64_pthread

これらは直接利用するのではなく、mk/blas.buildlink3.mkを経由して使うことで、 切り替えてビルド時に利用することができます。 mk/blas.buildlink3.mkで設定できるのは、まずは3つのBLAS_ACCEPTEDです。

  • netlib
  • openblas
  • openblas_pthread
  • openblas_openmp
  • accelerate.framework

ここで、accelerate.frameworkはNetBSDでは利用できないmacOSの機能ですので、除外して考えると、さきほどのパッケージとの関係は以下のようです。

  • netlib → math/blas、math/blas64
  • openblas → math/openblas、math/openblas64
  • openblas_pthread → math/openblas_pthread、math/openblas64_pthread
  • openblas_openmp → math/openblas_openmp、math/openblas64_openmp

でもこれだけでは、例えばmath/blasとmath/blas64を区別できません。これを区別するのがBLAS_INDEX64です。 これをyesに設定することで64付きのパッケージを選択できます。

pkgsrc/wip/llama.cppをマルチスレッド対応にする

と言うことで、llama.cppで使えるCPUで演算するBLASライブラリーを調べてみると、BLAS_ACCEPTEDで言うと、netlibとopenblas64ということがわかりました。 netlibはこれまで使って来て、マルチコアを活用できないものでした。活用できそうなmath/openblas64_pthread、math/openblas64_openmpを使えるようにしてみます。 pkgsrc/wip/llama.cppl/Makefileに以下のように追記してみます

BLAS_INDEX64=           yes
BLAS_ACCEPTED=          openblas_pthread openblas_openmp

ビルドして動作確認をしてみる

結果から言うと、openblas64_openmpは私の環境では正常にllama.cppを動かしてはくれませんでした。 全てのコアを使い切ってはくれますが、openblas_pthreadのように速やかに演算をしてはくれませんでした。 openblas_pthread、openblas_openmpそれぞれを使ったllama.cppをビルドするには、以下のようにします。

# make PKGSRC_BLAS_TYPES=openblas_openmp install
または
# make PKGSRC_BLAS_TYPES=openblas_pthread install

動作確認には、以前はllama-cliを使っていましたが、llama-serverとウェブブラウザーを使うのが良さそうです。 ChatGPT的なウェブページが提供されます。 IPv6で自ホスト以外からもアクセスできるようにする例です。 http://localhost:8080/をwww/firefox等で開くと利用できます。

$ llama-server --host :: --port 8080 -m ./models/gemma-2-2b-jpn-it-Q4_K_M.gguf

Firefoxで、espeak-ngによるtext-to-speechをする

この記事は、NetBSD Advent Calendar 2024の6日目の記事です。

Firefox for NetBSDでのtext-to-speech

昨年の今ごろに、festivalによるtext-to-speechをFirefox for NetBSDで試していました。 試してみると、pkgsrc/audio/festivalではなく、pkgsrc/audio/espeak-ngでも発声させることができました。

Firefoxをインストールする

pkgsrc/www/firefoxは、speechdオプションを有効にしてビルドしインストールする必要があります。 既定値ではspeechdオプションは有効ではないので、以下のように実行すれば良いでしょう。

# cd /usr/pkgsrc/www/firefox
# make PKG_OPTIONS.firefox=speechd install

必要なパッケージをインストールする

必要なのは、pkgsrc/audio/espeak-ngだけであるようです。 以下のように実行してインストールします。

# cd /usr/pkgsrc/audio/espeak-ng
# make install

speech-dispatcherを設定する

festivalの場合に設定した箇所に、espeak-ngを設定して行きます。 以下のパッチのように/usr/pkg/etc/speech-dispatcher/speechd.confを修正します。

--- /usr/pkg/etc/speech-dispatcher/speechd.conf.orig    2024-12-10 11:52:48.513672931 +0000
+++ /usr/pkg/etc/speech-dispatcher/speechd.conf
@@ -114,6 +114,7 @@ DefaultVolume 100
 # configuration.

 # DefaultLanguage "en-US"
+DefaultLanguage "en-US"


 # ----- MESSAGE DISPATCHING CONTROL -----
@@ -256,7 +257,7 @@ SymbolsPreprocFile "orca-chars.dic"
 #    or ~/.config/speech-dispatcher) or absolute

 #AddModule "espeak"                   "sd_espeak"    "espeak.conf"
-#AddModule "espeak-ng"                "sd_espeak-ng" "espeak-ng.conf"
+AddModule "espeak-ng"                "sd_espeak-ng" "espeak-ng.conf"
 #AddModule "festival"                 "sd_festival"  "festival.conf"
 #AddModule "flite"                    "sd_flite"     "flite.conf"
 #AddModule "ivona"                    "sd_ivona"     "ivona.conf"
@@ -290,11 +291,13 @@ SymbolsPreprocFile "orca-chars.dic"
 # must use one of the names of the modules loaded with AddModule.

 # DefaultModule espeak-ng
+DefaultModule espeak-ng

 # The LanguageDefaultModule selects which output modules are preferred
 # for specified languages.

 #LanguageDefaultModule "en"  "espeak"
+LanguageDefaultModule "en"  "espeak-ng"
 #LanguageDefaultModule "cs"  "festival"
 #LanguageDefaultModule "es"  "festival"
 
 

発声させてみる

Firefoxを一度終わらせ、再度起動します。 その上で、適当な英語で書かれたウェブページを開き、reader modeにします。 すると、ヘッドホンマークのtext-to-speechメニューが表示されます。 ここで、音声を選んで、▶アイコンで発声させられます。

ただ、festivalに増してあまり音質は良くないような気がします。 別途サーバーを起動しておかなくて良いのは利点かもしれません。

cdce(4)なUSB-Ethernetアダプターを使っている時に、ブリッジネットワークが使えなかった話

この記事は、NetBSD Advent Calendar 2024の3日目の記事です。

qemuで使うブリッジネットワークを用意したい

qemuで仮想マシンを使ってみるときには、qemuのユーザーネットワークが手軽ですが、ホスト側からアクセスしようとすると、自由度が低く面倒です。 そうなると、tap(4)とbridge(4)を使って、ホストと同じネットワークに接続したくなります。 私が通常使っているラップトップPCには、内蔵のEthernetデバイスはありません。 そして、過去にcdce(4)でしか認識されず、ure(4)としては認識されないUSB-Ethernetアダプターを使っていたのもあって、 以下のように/boot.cfgに設定しています。 これにより、滑てのure(4)なデバイスがcdce(4)なデバイスとして認識されます。

# cat /boot.cfg
(snip)
userconf=disable ure*
(snip)

ところが、cdce(4)として認識されているUSB-Ethernetデバイスをブリッジネットワークに参加させようとすると、 どうやっても通信ができないようでした。 もしかしたら、私のラップトップPCのxhciのせいかもしれませんが…。

ブリッジネットワークを設定する

The NetBSD guideのConfiguring bridged networking on a NetBSD host に記載のように、以下のようにすれば、ブリッジネットワークを設定できるはずです。 私は、以下のようにcdce(4)で設定してみました。

# ifconfig tap0 create
# ifconfig tap0 descr "NetBSD VM" up
# ifconfig bridge0 create
# ifconfig bridge0 descr "LAN VM bridge" up
# brconfig bridge0 add tap0 add cdce0

これで、qemuの仮想マシンを起動させても、そこで動かしているNetBSDから外のホストと同じネットワークにはアクセスできませんでした。 その時、以下のようにカーネルをエラーを出していました。

cdce0: watchdog timeout
cdce0: usb error on tx: IOERROR
cdce0: watchdog timeout
cdce0: usb error on tx: IOERROR
cdce0: watchdog timeout
cdce0: usb error on tx: IOERROR

とりあえずure(4)として使えばブリッジネットワークは構築できますが、同じ状態の人がいたら、参考になればと思います。

NetBSDからCanon LBP3100に印刷する

この記事は、NetBSD Advent Calendar 2024の2日目の記事です。

Canon LBP3100というプリンターについて

Canon LBP3100というプリンターは。Canonの安価なwinprinterです。 私は2015年3月に5,580円で購入しました。 トナーカートリッジはしばらく前になくなってしまいましたが、2,280円でサードパーティーのリサイクルトナーカートリッジを買ったので、まだしばらく使えればと思っています。

LBP3100はwinprinterだと書きましたが、実際にはCAPT (Canon Advanced Printing Technology)というページ記述言語を受け付けてくれます。 ただ、単純にCAPTフォーマットのデータをLBP3100に送ったら印刷されるという訳ではないようです。

CUPSで印刷する準備をする

CUPSは、今はPrinter ApplicationというIPSを受け付けて独自のプリンターへ出力する仕組みを推進しているようですが、今回はこれまで通りのフィルターコマンドを 使ってみます。 今回は、CAPTをリバースエンジニアリングして作られたcaptdriver 0.1.4.2-GxBというのを 使ってみることにします。

captdriverをビルドする

まず以下のようにして、https://github.com/mounaiban/captdriver/tree/0.1.4.2-GxB からソースコードをcloneします。

$ git clone git@github.com:mounaiban/captdriver.git
$ cd captdriver
$ git checkout 0.1.4.2-GxB

その上で、以下のように実行すれば、ビルドできます。

$ autoreconf -fi
$ ./configure
$ make

こうすると、src/rastertocaptというバイナリーファイルができます。

フィルタープログラムをインストールする

CUPSで印刷するには、フィルタープログラムとppdファイルが必要です。以下のようにインストールすれば良いでしょう。

# cp src/rastertocapt /usr/pkg/libexec/cups/filter
# mkdir /usr/pkg/share/cups/model

ppdファイルは0.4.2-GxBブランチには存在しないので、以下のようにブランチを切り替えてppdファイルを入手します。

$ git checkout master
# cp ppd/CanonLBP-2900-3000.ppd ppd/CanonLBP-3010-3018-3050.ppd /usr/pkg/share/cups/model

LBP3100で使うのはCanonLBP-3010-3018-3050.ppdの方です。

印刷する準備をする

次に、必要なパッケージをインストールしておきます。 以下のようにすれば良いでしょう。

# cd /usr/pkgsrc/print/cups-filters
# make install

cups-filtersは必須です。これがないと、captdriverはエラーになり利用することができません。

他にもCUPSを利用して印刷するプログラムが必要です。今回はpkgsrc/www/firefox-133.0を使うことにします。 (firefox-133.0はまだpkgsrc treeにcommitされていません。)

CUPS daemonを起動させ、プリンターを追加する

LBP3100はUSB接続しかないプリンターです。 Canon LBP3100をつなぐと、ulpt(4)として認識されます。 ですが、ugen(4)として認識されないとうまくプリンターとして認識されないようです。 /boot.cfgに以下のように追記して、再起動後にultp(4)を無効化するように設定します。

$ cat /boot.cfg
userconf=disable ulpt*

続いて、cupsdをNetBSD起動時に起動させるようにします。

$ cat /etc/rc.conf
(snip)
cupsd=YES
(snip>

ここまで設定できたら、NetBSDを再起動させます。

プリンターを追加する

ウェブブラウザーでhttp://localhost:631/を開きます。Administrationを選択します。ログインが求められたらNetBSDへのログイン情報を入力します。

LBP3100とNetBSDマシンをUSB A to Bケーブルで接続し、LBP3100の電源を入れた上で、 Add Printerボタンを押します。

Local PrinterのCanon LBP3100/LBP3108/LBP3150 (Canon LBP3100/LBP3108/LBP3150)を選択します。

私はプリンター名は単に「LBP3100」と変更しました。

インストールしてあるPPDファイルを選択するため、MakeではCanon Incを選択します。

PPDは「Canon Inc LBP3010/LBP3018/LBP3050 r2c, 0.1.4 (en, en)」を選択します。

無事、LBP3100をプリンターとして追加することができました。

印刷してみる

例えばFirefoxだと、下図のように印刷することができます。画質も悪くなさそうです。

plgarc/wip/llama.cppでpkgsrcのBLASサポートを探る

この記事は、 NetBSD Advent Calendar 2024 の13日目の記事です。 llama.cppを使ってみる 以前に、 NetBSD/amd64でllama.cppを使ってみる という記事で llama.cpp を使ってみていました。 あれか...