Ollama と Testcontainers を使用して簡単に Hugging Face の AI/ML モデルを実行する方法

Hugging Face は現在、70 万以上のモデルをホストしており、その数は継続的に増えています。これは、AI/ML モデルの中でも最高レベルのリポジトリで、一般的なニーズだけでなく、高度かつ専門的なニーズにも対応しています。

AI/ML モデルの採用が加速するにつれて、それらをプロジェクトに統合することを望むアプリケーション開発者も増えています。ただし、設定が複雑で、開発者にとって使いやすいツールがないため、導入への障壁は依然として高いままです。もし AI/ML モデルのデプロイが、データベースを起動するのと同じくらい簡単だったら、その方法を知りたいですか?興味のある方は、以下をご確認ください。

Ollama と Testcontainers の概要

先日、Ollama は Hugging Face のランニング モデルのサポート追加を発表しました。これにより Olluma ユーザーは、Hugging Face の AI/ML コンポーネントの豊富なエコシステムを活用できるようになりました。

また、Testcontainers ライブラリではすでに Ollama モジュールを提供しているため、Ollama を実行する方法を知らなくても、Docker を使用して Ollama でコンテナーを簡単にスピンアップできます。

import org.testcontainers.ollama.OllamaContainer; 
 
var ollama = new OllamaContainer("ollama/ollama:0.1.44"); 
ollama.start();

上記は、Ollama を Docker コンテナー内で簡単に実行するためのコードです。

Ollama でモデルを実行する

デフォルトでは、Ollama には何のモデルが含まれていないため、使用するモデルをダウンロードする必要があります。Testcontainers の利用で、Testcontainers が提供する execInContainer API を用いて、この手順を簡素化します。

ollama.execInContainer("ollama", "pull", "moondream");

この時点で、Ollama API 経由で moondream モデル利用する準備が整いましたが、よく考えてみてください。このモデルはコンテナー内で実行されているため、コンテナーを終了したらどうなるのか、新しいコンテナーをスピンアップして、モデルを再度プルする必要があるのか、疑問に思いませんか?これらのモデルは非常に大きくなる可能性があるため、できればこのような心配はしたくないですよね。

ありがたいことに、Testcontainers は特定の状況 (コンテナーを終了するなど) に対処できるように、プログラムから簡単にコンテナーのイメージを保存できる API を提供しています。

public void createImage(String imageName) {
var ollama = new OllamaContainer("ollama/ollama:0.1.44");
ollama.start();
ollama.execInContainer("ollama", "pull", "moondream");
ollama.commitToImage(imageName);
}

このコードにより、一度イメージを作っておけば、次回以降はそのイメージを使って簡単にコンテナーを立ち上げられ、モデルの再取得が不要になります。以下がそのパターンです。

var imageName = "tc-ollama-moondream";
var ollama = new OllamaContainer(DockerImageName.parse(imageName)
.asCompatibleSubstituteFor("ollama/ollama:0.1.44"));
try {
ollama.start();
} catch (ContainerFetchException ex) {
// If image doesn't exist, create it. Subsequent runs will reuse the image.
createImage(imageName);
ollama.start();
}

これで、モデルを使用する準備ができました。Ollama で実行されているため、その API を操作できます。

var image = getImageInBase64("/whale.jpeg");
String response = given()
.baseUri(ollama.getEndpoint())
.header(new Header("Content-Type", "application/json"))
.body(new CompletionRequest("moondream:latest", "Describe the image.", Collections.singletonList(image), false))
.post("/api/generate")
.getBody().as(CompletionResponse.class).response();
 
System.out.println("Response from LLM " + response);

Hugging Face モデルの使用

前の例では、Ollama で既に提供されているモデルを使用して説明しましたが、先日より Ollama で Hugging Face モデルを使用できるようになったため、現在利用可能なモデル オプションは数千以上となりました。 

Hugging Face in Ollama のモデルを使用するには、GGUF ファイルが必要ですが、現在、Hugging Face では 20,647 もの GGUF 形式モデルが利用可能です。素晴らしいですね!

Ollama で Hugging Face モデルを実行する手順は簡単ですが、Docker はカスタム OllamaHuggingFaceContainer にスクリプト化することで、さらにこのプロセスを簡略化しました。このカスタム コンテナーはデフォルト ライブラリに含まれていないため、 OllamaHuggingFaceContainer の実装をコピーして貼り付け、ニーズに合わせてカスタマイズできます。

Hugging Face モデルを実行するには、次の操作を行います。

public void createImage(String imageName, String repository, String model) {
var model = new OllamaHuggingFaceContainer.HuggingFaceModel(repository, model);
var huggingFaceContainer = new OllamaHuggingFaceContainer(hfModel);
huggingFaceContainer.start();
huggingFaceContainer.commitToImage(imageName);
}

上記のようにリポジトリ名とモデル ファイルを指定することで、Testcontainers を介して Ollama で Hugging Face モデルを実行できます。 

埋め込みモデルを使用した例チャット モデルを使用した例は、GitHub にあります。

コンテナーをカスタマイズする

Testcontainers を使用する主なメリットの 1 つは、複雑な設定を管理しやすいコンテナーへカプセル化すると、特定のプロジェクト ニーズに合わせてコンテナーの設定を柔軟にカスタマイズできるようになることです。

たとえば、要件に合わせたカスタム コンテナーを作成できます。以下は、Hugging Face から DavidAU/DistiLabelOrca-TinyLLama-1.1B-Q8_0-GGUF モデルをスピンアップするために特化したコンテナーの TinyLlama の例です。

public class TinyLlama extends OllamaContainer {
 
    private final String imageName;
 
    public TinyLlama(String imageName) {
        super(DockerImageName.parse(imageName)
.asCompatibleSubstituteFor("ollama/ollama:0.1.44"));
        this.imageName = imageName;
    }
 
    public void createImage(String imageName) {
        var ollama = new OllamaContainer("ollama/ollama:0.1.44");
        ollama.start();
        try {
            ollama.execInContainer("apt-get", "update");
            ollama.execInContainer("apt-get", "upgrade", "-y");
            ollama.execInContainer("apt-get", "install", "-y", "python3-pip");
            ollama.execInContainer("pip", "install", "huggingface-hub");
            ollama.execInContainer(
                    "huggingface-cli",
                    "download",
                    "DavidAU/DistiLabelOrca-TinyLLama-1.1B-Q8_0-GGUF",
                    "distilabelorca-tinyllama-1.1b.Q8_0.gguf",
                    "--local-dir",
                    "."
            );
            ollama.execInContainer(
                    "sh",
                    "-c",
                    String.format("echo '%s' > Modelfile", "FROM distilabelorca-tinyllama-1.1b.Q8_0.gguf")
            );
            ollama.execInContainer("ollama", "create", "distilabelorca-tinyllama-1.1b.Q8_0.gguf", "-f", "Modelfile");
            ollama.execInContainer("rm", "distilabelorca-tinyllama-1.1b.Q8_0.gguf");
            ollama.commitToImage(imageName);
        } catch (IOException | InterruptedException e) {
            throw new ContainerFetchException(e.getMessage());
        }
    }
 
    public String getModelName() {
        return "distilabelorca-tinyllama-1.1b.Q8_0.gguf";
    }
 
    @Override
    public void start() {
        try {
            super.start();
        } catch (ContainerFetchException ex) {
            // If image doesn't exist, create it. Subsequent runs will reuse the image.
            createImage(imageName);
            super.start();
        }
    }
}

一度定義すれば、アプリケーションでカスタム コンテナーを簡単にインスタンス化して利用できます。

var tinyLlama = new TinyLlama("example");
tinyLlama.start();
String response = given()
.baseUri(tinyLlama.getEndpoint())
.header(new Header("Content-Type", "application/json"))
.body(new CompletionRequest(tinyLlama.getModelName() + ":latest", List.of(new Message("user", "What is the capital of France?")), false))
.post("/api/chat")
.getBody().as(ChatResponse.class).message.content;
System.out.println("Response from LLM " + response);

TinyLlama クラスの内部で全ての実装の詳細が隠されています。そのため、ユーザーはモデルを Ollama にインストールする方法や、GGUF が何であるか、huggingface-cli を取得するために huggingface-hub のインストールが必要なことを知る必要がありません。

このアプローチの利点

  • プログラムによるアクセス: 開発者は、Hugging Face エコシステムにプログラムでシームレスにアクセスできます。
  • 再現可能な構成: 設定からライフサイクル管理まで、すべての構成が体系化され、チーム メンバーと CI 環境全体での再現性を確保できます。
  • 使い慣れたワークフロー: コンテナーの使用で、コンテナー化に精通している開発者は AI/ML モデルを簡単に統合でき、プロセスにアクセスしやすくなります。
  • 自動設定: 開発者に簡単なクローンと実行のエクスペリエンスを提供します。

このアプローチは、Testcontainers モジュールで提供される自動化とカプセル化によってHugging Face と Ollama の両方の長所を活かし、強力な AI ツールをよりアクセスしやすく、かつ管理しやすくします。

まとめ

AI モデルとアプリケーション統合は、必ずしも難しい作業ということではありません。Ollama と Testcontainers の活用で、最小限の労力で Hugging Face モデルをプロジェクトにシームレスに組み込めます。このアプローチにより、開発環境プロセスの設定を簡素化できるだけでなく、再現性と使いやすさも保証されます。モデルをプログラムで管理し、一貫性のある環境を提供するコンテナー化機能で、開発者は複雑な設定手順に煩わされることなく、革新的なソリューションの構築に集中できます。

Ollama の Hugging Face モデルのサポート追加と Testcontainers の堅牢なコンテナー管理機能の組み合わせは、最新 AI 開発のための強力なツールキットです。これらのツールは、高度なモデルにアクセスし管理するための重要な役割を果たします。Testcontainers と Olluma を利用して、Hugging Face モデルを実行してみましょう!

現在 Testcontainers は Docker コンテナー上で利用できます

2023 年 12 月、Docker 社が Testcontainers の開発会社である AtomicJar を買収し、現在、Atomic Jar は Docker の一部として Testcontainers を提供しています。Docker は、Docker Desktop や Docker Scout などにより、すでにソフトウェア開発の「インナーループ」のステップであるビルドや検証、実行、デバッグ、共有の加速をサポートしていますが、Testcontainers により、「テスト」の信頼性向上と加速のサポートを追加しました。これにより、Docker を使用する開発者は、より品質の高いソフトウェアをより速く提供できるようになります。


エクセルソフトは Docker の Preferred Reseller として、Docker Business を販売しています。2022 年 1 月 31 日以降、中・大規模組織による Docker Desktop の利用には有料サブスクリプションが必要となっています。詳細は、弊社 Web サイトをご確認ください。


*本記事は、Docker 社が提供している以下の記事から抜粋・転載したものです。

Ollama と testcontainers を使用してプログラムで抱きしめる顔モデルを実行する方法

Docker の最新情報をお届けするエクセルソフトのメールニュース登録はこちら

タイトルとURLをコピーしました