1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Livebook と Ollama で Phi-4 モデルによる AI チャットを構築する

Last updated at Posted at 2025-02-22

はじめに

以前の記事で Ollama と Livebook を連携する手法を紹介しました

本記事では Ollama と Livebook で簡易的な AI チャットを実装してみます

AI には比較的軽量で CPU 環境でもそれなりに速く動いてくれる Phi-4 を使用します

実装したノートブックはこちら

コンテナの準備

本記事では Livebook と Ollam をコンテナで起動します

docker-compose.with-ollama.yml

---

services:
  livebook_with_ollama:
    image: ghcr.io/livebook-dev/livebook:0.14.7
    container_name: livebook_with_ollama
    ports:
      - '8080:8080'
      - '8081:8081'
    volumes:
      - ./tmp:/tmp

  ollama:
    image: ollama/ollama:0.5.11
    container_name: ollama_for_livebook
    ports:
      - '11434:11434'
    volumes:
      - ollama:/root/.ollama

volumes:
  ollama:

コンテナのビルド・起動

以下のコマンドでコンテナをビルド、起動します

docker compose --file docker-compose.with-ollama.yml up

両方のビルドが完了したら Livebook の URL にアクセスします

Livebook 上での AI チャットの実装

セットアップ

Livebook で新しいノートブックを開き、セットアップセルで以下のコードを実行します

Mix.install([
  {:ollama, "~> 0.8"},
  {:kino, "~> 0.14"}
])

モデルの用意

コンテナで起動している Ollama にアクセスするためのクライアントを用意します

URLでしていしている「ollama」の部分は docker-compose で指定したサービス名です

応答に時間がかかることを想定して、 receive_timeout に 300 秒を指定します

client = Ollama.init(base_url: "http://ollama:11434/api", receive_timeout: 300_000)

クライアントで Phi-4 のモデルをダウンロードします

Ollama.pull_model(client, name: "phi4")

読み込みに時間がかかるので、実行前に読み込んでおきます

Ollama.preload(client, model: "phi4")

Ollama によるストリーミング応答

ストリーミングで受け取ったトークン毎に表示を更新します

回答表示用のフレームを用意します

answer_frame = Kino.Frame.new()

回答用の関数を用意します

ストリーミングで処理した後、全部のトークンを結合して返すようにしています

answer = fn input, frame ->
  {:ok, stream} =
    Ollama.completion(
      client,
      model: "phi4",
      prompt: input,
      stream: true
    )

  stream
  |> Stream.transform("AI: ", fn chunk, acc ->
    response = acc <> chunk["response"]

    markdown = Kino.Markdown.new(response)
    Kino.Frame.render(frame, markdown)

    {[chunk["response"]], response}
  end)
  |> Enum.join()
end

Phi-4 は日本文化についても結構知っているので、ドラえもんについて質問してみましょう

answer.("ドラえもんについて100文字程度で説明して", answer_frame)

実行結果

doraemon.gif

フォームの作成

チャットアプリらしいフォームを用意します

# 出力用フレーム
output_frame = Kino.Frame.new()

# ストリーミング用フレーム
stream_frame = Kino.Frame.new()

# 入力用フォーム
input_form =
  Kino.Control.form(
    [
      input_text: Kino.Input.textarea("メッセージ")
    ],
    submit: "送信"
  )


Kino.Frame.render(output_frame, Kino.Markdown.new(""))
Kino.Frame.render(stream_frame, Kino.Markdown.new(""))

# フォーム送信時の処理
Kino.listen(input_form, fn %{data: %{input_text: input}} ->
  Kino.Frame.append(output_frame, Kino.Markdown.new("あなた: " <> input))
  full_response = answer.(input, stream_frame)
  Kino.Frame.render(stream_frame, Kino.Markdown.new(""))
  Kino.Frame.append(output_frame, Kino.Markdown.new("AI: " <> full_response))
end)

# 入出力を並べて表示
Kino.Layout.grid([output_frame, stream_frame, input_form], columns: 1)

実行結果

okonomiyaki.gif

AI チャットが実装できました

まとめ

Livebook と Ollama で AI チャットが実装できました

Phi-4 であればローカルマシンでも十分な速度で応答してくれます

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?