タイトルのとおり、llama.cppのRubyバインディングであるllama_cpp.rbのネイティブ拡張のコードを、C++からC言語に書き換えて、v0.18.0としてリリースした。
llama.cppは、本体はC++で書かれているが、llama.hは、C言語でも呼び出せる形で書かれている。libllama.soをリンクして、llama.hをincludeするみたいな使い方ならC言語で問題ない。llama_cpp.rbは、以前はllama.cppのコードを同梱する形を取っていたが、いまは共有ライブラリを探してリンクする形にしてあるので、ネイティブ拡張のコードをC言語で書き換えることができる。
今回、C言語で書き換えたのは、開発にひとつのケリをつけるためである。Rubyのネイティブ拡張をC++で書くのは、王道ではないので、forkして改造するにもコードリーディングからして大変だったと思う。今回、C言語で教科書どおりのネイティブ拡張に書き換えた。テクいことしなければbindingが書けないと思った関数は、そもそもbindingを実装しなかった。これで、Rubyのネイティブ拡張の基礎知識があれば、llama_cpp.rbを改造できると思う。
llama.cppの変更は早く、APIもコロコロかわる。最近もllama_vocabというのが導入されて(以前から予告はされてた)、わりとインターフェースが大きく変わった。bindingライブラリを作るのに、はりついて変更を見守る必要があり、結構たいへんなのである。というわけで、llama_cpp.rbの継続的な開発を諦めた。今後は「気が向いたら」最新版に追従するぐらいの気持ちでいる。
llama_cpp.rbの開発を続けたいという人が出てきたときのために、今回、C言語でネイティブ拡張の作法にのっとった感じで実装しなおした。インターフェースも、クラスからメソッドが生えてるオブジェクト指向っぽいものから、C言語そのままの構造体を関数に渡す感じ(構造体をラップしたクラスをモジュール関数に与える感じ)のものにした。llama.cppに新しい関数が追加されても、わりとそのままbindingを書けばよい。
これで、一つ、今年やりたいことを達成できました。