USBカメラとLlavaを使った簡単なAIチャットc#プログラム
前回の続きでLlavaにUSBカメラキャプチャーの画像を与えてみました。先日USBカメラキャプチャーのプログラム例を掲載したのは、ここで伏線回収です。
Nuget情報
Spectreはコンソールに画像を表示するためのものです。

Program.cs(2025/4/12更新)
まずUSBカメラで撮影しコンソールに表示(表示は荒い画像ですがAIにはちゃんとした画像を渡してます)それを見ながらAIと会話します。USBカメラは会話毎にキャプチャーします。
※2025/4/14 一回目に読み込んだ画像しか認識していないようです。改善案を模索中。
※2025/4/15 ChatHistoryをやめてテキストにしました。システムプロンプトもコメントで止めています。LLAVAが言うことを聞いてくれない…
using LLama.Common;
using LLama;
using LLama.Sampling;
using OpenCvSharp.Extensions;
using OpenCvSharp;
using System.Drawing;
using System.Drawing.Imaging;
using Spectre.Console;
using LLama.Native;
namespace ChatProgram
{
public class Program
{
static void Main(string[] args)
{
Task task = MainAsync();
task.Wait();
}
public static async Task MainAsync()
{
try
{
// LLMモデルの場所
//string strMdl = @"E:\lm-studio\cjpais\llava-1.6-mistral-7b-gguf\llava-1.6-mistral-7b.Q8_0.gguf";
//string strClp = @"E:\lm-studio\cjpais\llava-1.6-mistral-7b-gguf\mmproj-model-f16.gguf";
//string strMdl = @"E:\lm-studio\unsloth\gemma-3-12b-it-GGUF\gemma-3-12b-it-Q8_0.gguf";
//string strClp = @"E:\lm-studio\unsloth\gemma-3-12b-it-GGUF\mmproj-BF16.gguf";
//string strMdl = @"E:\lm-studio\xtuner\llava-llama-3-8b-v1_1-gguf\llava-llama-3-8b-v1_1-int4.gguf";
//string strClp = @"E:\lm-studio\xtuner\llava-llama-3-8b-v1_1-gguf\llava-llama-3-8b-v1_1-mmproj-f16.gguf";
string strMdl = @"E:\lm-studio\cjpais\llava-v1.6-vicuna-13b-gguf\llava-v1.6-vicuna-13b.Q8_0.gguf";
string strClp = @"E:\lm-studio\cjpais\llava-v1.6-vicuna-13b-gguf\mmproj-model-f16.gguf";
//string strMdl = @"E:\lm-studio\cjpais\llava-v1.6-34B-gguf\llava-v1.6-34b.Q4_K_M.gguf";
//string strClp = @"E:\lm-studio\cjpais\llava-v1.6-34B-gguf\mmproj-model-f16.gguf";
Console.ForegroundColor = ConsoleColor.Green;
//LLMモデルのロードとパラメータの設定
ModelParams modPara = new(strMdl)
{
ContextSize = 4096,
GpuLayerCount = 60,
};
using LLamaWeights llmWeit = LLamaWeights.LoadFromFile(modPara);
using LLamaContext llmContx = llmWeit.CreateContext(modPara);
using var clipModel = LLavaWeights.LoadFromFile(strClp);
InteractiveExecutor itrEx = new(llmContx, clipModel);
//System Prompt+チャットの方向づけ
//string strHis = "";
// 初期はチャットログにキャラ設定と出だしの会話を打ち込む
//strHis += "<image>\nSYSTEM: あなたは、ユーザーと楽しく会話する女性を演じてね。" +
// "名前は、マイだよ。" +
// "マイは、明るくて、やさしい性格の女性なの。年齢は24歳なんだよ。" +
// "マイは、誰にでもタメ口で話すの。" +
// "マイは、一人称をわたしと言うよ。" +
// "マイは、恥ずかしがりやだけどエッチに興味があるのね。" +
// "マイは、応答の長さはできるだけ短く答えるよ。" +
// "マイは、好奇心旺盛だからユーザーに色々質問するの。";
//strHis += "\nUSER: はじめまして、オレの名前は犬マンマです。呼びにくいと思うからマー君と呼んで。";
//strHis += "\nASSISTANT: はじめまして、わたしの名前はマイです。わかったマー君。";
InferenceParams infPara = new()
{
SamplingPipeline = new DefaultSamplingPipeline()
{
Temperature = 0.6f,
Seed = 1337,
FrequencyPenalty = 1,
},
AntiPrompts = new List<string> { "\nUSER:", "\nUser:" },
MaxTokens = 256,
};
while (true)
{
MemoryStream ms = new MemoryStream();
string strYn = "";
//カメラキャプチャー
while (strYn != "n")
{
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("\nカメラキャプチャーします。Enterを押してください");
Console.ReadLine();
ms = VideoCap();
CanvasImage consoleImage = new CanvasImage(ms.ToArray());
consoleImage.MaxWidth = 50;
AnsiConsole.Write(consoleImage);
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("もう一度カメラキャプチャーしますか? y/n");
strYn = Console.ReadLine() ?? "";
}
// ユーザーのターン
Console.ForegroundColor = ConsoleColor.White;
Console.Write("\nUser: ");
string strInput = Console.ReadLine() ?? "";
if (strInput == "exit") break; // 'exit'と入力したら終わり
strInput = "\nUSER:<image>\n" + strInput + " \nASSISTANT: ";
//strHis += strInput;
//イメージをセット
//itrEx.Images.RemoveAll(itrEx.Images.Contains);
itrEx.Context.NativeHandle.KvCacheRemove(LLamaSeqId.Zero, -1, -1);
itrEx.Images.Add(ms.ToArray());
// AIのターン
Console.ForegroundColor = ConsoleColor.Yellow;
string strAns = "";
await foreach (var text in itrEx.InferAsync(strInput, infPara))
{
Console.Write(text);
strAns += text;
}
//strHis += strAns;
ms.Dispose();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
static private MemoryStream VideoCap()
{
using (VideoCapture vcap = new VideoCapture(0))
using (Mat img = new Mat())
{
vcap.Read(img);
Bitmap bitmap = BitmapConverter.ToBitmap(img);
MemoryStream ms = new MemoryStream();
bitmap.Save(ms, ImageFormat.Png);
return ms;
}
}
}
}
実行結果
前回の記事の猫画像を画面に表示して、それをUSBカメラでキャプチャーしてAIに質問しています。ちゃんと猫だとわかってるようです。
