phi4 を .NET Aspire で使ってみる
Ollama に phi4 が来てたので早速使ってみようと思います。
.NET Aspire の Community Toolkit に Ollama integration があるので簡単に使うことが出来ます。
やってみよう
.NET Aspire の空のアプリのプロジェクトテンプレートから始めます。
AppHost
プロジェクトに CommunityToolkit.Aspire.Hosting.Ollama
を追加します。
そして Program.cs
に以下のコードを追加します。
var builder = DistributedApplication.CreateBuilder(args);
var ollama = builder.AddOllama("ollama")
// モデルのキャッシュを残す
.WithDataVolume()
// GPU があれば使う
.WithContainerRuntimeArgs("--gpus=all")
// Open WebUI を追加
.WithOpenWebUI();
// phi4 を追加
var phi4 = ollama.AddModel("phi4");
builder.Build().Run();
これで実行すると .NET Aspire のダッシュボードが起動して phi4 のダウンロードが始まります。
コンソールログを見ると以下のようにダウンロードの進捗が確認できます。
2025-01-09T10:16:14 Unable to find image 'ollama/ollama:0.5.1' locally
2025-01-09T10:16:16 0.5.1: Pulling from ollama/ollama
2025-01-09T10:16:16 6414378b6477: Already exists
2025-01-09T10:16:16 f88ef0812532: Already exists
2025-01-09T10:16:16 a42005f63108: Already exists
2025-01-09T10:16:16 2281cc9d5261: Pulling fs layer
2025-01-09T10:17:25 2281cc9d5261: Verifying Checksum
2025-01-09T10:17:25 2281cc9d5261: Download complete
Ollama の Docker image のダウンロードが終わると次は以下のように phi4 のモデルのダウンロードをしている様子が確認できます。
しばらく待っていると全てが Running のステータスになります。Open WebUI のエンドポイントを開くと以下のようにチャットをして試すことが出来ます。ちゃんと phi4 に返事をもらえました!(時間は結構かかりました…)
では .NET のアプリから呼んでみましょう。今回は WPF で Generic Host を使ってみる でやった方法で WPF で汎用ホストを使う感じで行こうと思います。
汎用ホストを使う WPF アプリのひな型が出来たら以下のパッケージを WPF アプリに追加します。
CommunityToolkit.Aspire.OllamaSharp
そして WPF アプリの Program.cs
(汎用ホストを使うようにするために追加したものです) に以下の 1 行を追加してクライアントを登録します。
builder.AddOllamaSharpChatClient("ollama-phi4");
後は画面を作っていきます。疎通確認が主目的なので適当に作ります。
ボタンやテキストボックスを置いた簡単な画面を作ります。
<Window x:Class="Phi4ClientWpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Phi4ClientWpfApp"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<TextBox x:Name="textBox" />
<Button Content="Send" Click="Button_Click" />
<TextBlock x:Name="textBlock" />
</StackPanel>
</Window>
コードビハインドでは Microsoft.Extensions.AI
の IChatClient
を使って素直にチャットを送信してみます。
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Logging;
using System.Windows;
namespace Phi4ClientWpfApp;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private readonly IChatClient _client;
private readonly ILogger<MainWindow> _logger;
// デザイナー用のコンストラクターなので null 許容参照型系の警告は無視
#pragma warning disable CS8618
public MainWindow()
#pragma warning restore CS8618
{
InitializeComponent();
}
public MainWindow(IChatClient client,
ILogger<MainWindow> logger) : this()
{
_client = client;
_logger = logger;
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
var r = await _client.CompleteAsync(textBox.Text);
if (r.FinishReason != ChatFinishReason.Stop)
{
_logger.LogWarning("Stop 以外の理由でチャットが終了しました: {finishReason}", r.FinishReason);
MessageBox.Show("Failed");
return;
}
textBlock.Text = r.Message.Text;
}
}
実行してみると以下のようにチャットが送信できることが確認できます。
非常に簡単に試すことができました!
まとめ
.NET Aspire を使うと、こういう SLM をとりあえずローカルで動かした試すようなことが簡単にできます。またコードを clone して実行するだけで基本的に他の人も同じように動かすことが出来るのでとっても便利です。
コードは GitHub に置いておきます。Docker があって VS 2022 があれば動くはずです。
Discussion