数値解析系

2024年12月 1日 (日)

Googleの生成AI「Gemini Advanced」に入ってみた

入ったばかりの月は無料ですが、そのまま継続し、月額2900円を払うつもりでGoogleの生成AI「Gemini Advanced」を使うことにしました。

Gemini

といっても自腹なので、仕事で使うわけではない・・・といいつつ、仕事そのものではないものの、仕事で使う分析の手法などを提示させることに使えないかなぁと思い、契約することに。

実際、私の知ってる分析者も、かなり生成AIを自腹で使ってます。一番多いのがOpenAIのChatGPT Proですが、私はあえてGoogle Gemini Advancedにしました。
話によると、ChatGPTの方が何かと賢いようです。が、こういうのはGoogleってすぐに追いついてくることが多いので、ここはGeminiにするかと思い、決めた次第。
以前に「notebookLM」を使って好印象だったこともありますが。
(Googleの生成AI「Gemini 1.5 Pro」を使ったサービス「notebookLM」がすごいらしいので試してみた: EeePCの軌跡)

てことで、せっかくだから分析っぽいことをやらせてみることにしました。何か手ごろなデータがないかと思って探してみましたが、出てきたのは「血圧値.csv」というデータです。

7月の健康診断以来、毎日朝晩、安静時の値を測り続けてます。
まあ要するに、健康診断の血圧で引っかかったわけで、そろそろ血圧の薬を飲まなきゃいけないのかなぁと覚悟しているところです。
それで毎日、血圧を記録するよう言われております。

さて、わざわざそんなデータがあるので、そのCSVを読み込ませて、ちょっと分析っぽいことをやらせてみました。

最初に打ち込んだプロンプトは、以下。

次の時系列データを読み込み、分析・予測を行ってください。
「days」列が、時間を表します(単位は日)
「MAX_blood_pressure」が最高血圧値
「min_blood_pressure」が最低血圧値
このデータを用いて、最大血圧値、最低血圧値それぞれの1週間おきの平均値、最大値、最小値を求め、グラフ化してください。

で、出てきたのは以下のようなグラフ。

20241201-160614_20241201164201

上の3本が「最高血圧」、下が「最低血圧」と呼ばれるものです。それを週ごとの平均値、最大値、最小値をグラフ化したものです。
特に11月くらいからですが、最高血圧値が上昇傾向にあるなぁと思い始めてます。
ということで、次のようなプロンプトを打ってみました。

最高血圧値について、どのような傾向にあるかを考察してください。

で、帰ってきた答えは以下。

グラフから、最高血圧値は週によって変動があるものの、全体的には上昇傾向にあることが分かります。
また、最低血圧値は、週によって変動があるものの、全体的には横ばい傾向にあることが分かります。

実際には、上の週ごとの平均グラフを最高血圧、最低血圧の両方を書き出した上で、上のような結論を述べておりました。
そこで、今あるデータ(0~22週)に基づいて、30週目(今から2か月後くらい)に最高血圧値がどれくらいになるか、予測させてみました。

最高血圧値は上昇傾向とありますが、30週目にはどれくらいの値になるか、予測できますか?
また、予測に用いる手法も提示してください。

返ってきた答えはこちら。

30週目の最高血圧値を予測するために、時系列データ分析の手法であるARIMAモデルを使用します。
ARIMAモデルを用いて予測した結果、30週目の最高血圧値は約137.66と予測されました。
ただし、この予測はあくまで参考値であり、実際の値とは異なる可能性があります。
また、ARIMAモデルの次数(p, d, q)はデータによって異なるため、自己相関関数(ACF)や偏自己相関関数(PACF)などを用いて適切な次数を判断する必要があります。
ここでは仮に(5, 1, 0)としています。

137.66かぁ・・・安静時の最高血圧値が135、最低血圧が85を越えると「循環器内科へ行くように」と勧められるのが弊社ですが、こりゃあもうダメそうですね。そろそろフォローが来るはずなので、先に行っておこうかな、などと考えている最中です。

という生々しい話は置いておき、ここでは「ARIMAモデル」という手法を使っていると書いてありました。
あまり聞いたことがない手法ですが、いかに解説があります。

【気象データで時系列解析⑥】ARIMAモデル #Python - Qiita

分かったような、分からんような感じですが、こんな手法があるんだなぁということを教えられました。
なお、Pythonのコードを裏で作っているようで、それも入手することが可能です。
今度、時系列データを解析することがあったら、使ってみようかなと。

社内やグループ会社で、データ分析に関する問題解決の教え役みたいなことをやってるんですが、いろいろなデータが出てきて、そのたびに専門外のことも含めていろいろと聞かれます。
こういう時はググってどうにか探してましたが、そのテーマと似たようなダミーデータを作るか、公開データを利用して、分析手法などを聞き出すということをさせてみたいと思ってます。

他の人も、そういう使い方をさせているみたいです。

が、私の場合はもう一つ使い道がありまして、それが「小説のアイデア作成」です。
まあ要するに、もやっと思い浮かんだアイデアを入れて、プロットを書かせてみたりするわけです。

20241201-163931

もっとも、これに小説そのものを書かせようという気はなくて、あくまでもアイデアや設定の参考を書かせるというものです。
実際に小説を書かせてはみたのですが、やはりこちらが意図したとおりのものを書いてくれるわけではない上に、文章も短すぎる。飛躍が多い。
想像しながら文字化するので、あくまでもその「想像部分」を膨らませるのが目的です。

なお、架空の地名や名前を考えさせるのは便利ですね。
ただ、とある作品で名前の付け方が変だ、という騒ぎが海外で起きたことがある(日本語的には「関西人」みたいな名前)ので、そういうのに陥らないようにある程度調べて使うつもりですが。

そういえば会社ではCopilotの企業版を使っておりますが、あれがあまり賢くない。
画像生成も可能なので「草原を走るハ〇エース」なるものを書かせてみましたが、どうもいまいちな感じ。
CopilotのImage Createrって、いかにもAIとわかる絵柄なんですよね。ちょっと写実的とは言い難い。イラストに近い感じ。

同じものを、Gemini Advancedにも書かせてみました。

Gemini_generated_image_5mqkoy5mqkoy5mqk

こちらの方が、より写実的な絵ができました。なんかちょっと中央ラインが・・・という気もしますが、一発でここまで描けるのは大したものです。

ということで、生活の一部に、本格的に生成AIを入れていこうという話でした。
いいサービスが出てきたら、また乗り換えることもあるかもしれませんが、しばらくはGemini Advancedかなぁ。


小説を書く人のAI活用術 AIとの対話で物語のアイデアが広がる

2024年9月14日 (土)

Tanuki-8Bの4ビット量子化ggufモデルでRAGをやってみました

なんかRAGネタ増えてますが、まあ、お付き合いください。
それくらい、最近のローカルLLMの進化が激しいってことです。

前回の記事(純日本産なローカルLLM「Tanuki-8B」を試してみた: EeePCの軌跡)でgguf版を落としたけど支離滅裂な挙動だったと書きましたが、あれは嘘だ。

というか、ちゃんとした(?)gguf版を下記から落としたら、ちゃんと使えました。

team-hatakeyama-phase2/Tanuki-8B-dpo-v1.0-GGUF at main

で、落としたのは「Tanuki-8B-dpo-v1.0-Q4_K_M.gguf」という4ビット化されたもの。

前回の記事(純日本産なローカルLLM「Tanuki-8B」を試してみた: EeePCの軌跡)のモデルを「Tanuki-8B-dpo-v1.0-Q4_K_M.gguf」に置き換えてみましたが。

Q

おすすめの名古屋飯を5つ教えてください。

A
名古屋市(なごやし)は、愛知県に位置する都市で、美味しいご当地グルメが豊富です。以下に、名古屋市でおすすめのおすめしを5つご紹介します。

1. 名古屋コーチンのひつまぶし:

名古屋コーチンは地元産の鶏肉で、その旨味と柔らかさが特徴です。特に「ひつまぶし」として提供されることが多く、まずはそ のまま食べてから、薬味や出汁をかけて楽しむことができます。
2. みそカツ:

味噌ダレをたっぷりかけたトンカツで、サクサクとした衣と濃厚な味噌の風味が絶品です。ご飯と一緒に食べることで、さらに満 足感が増します。
3. 名古屋カレーうどん:

カレーライスのようにルーがかかったうどんで、名古屋特有の甘辛いカレールーが特徴です。寒い季節には体を温める一品として おすすめです。
4. ひつまぶし風のうなぎ丼:

うなぎ(鰻)は名古屋市の名物で、特に「ひつまぶし」スタイルで提供されることが多いです。蒲焼にしたうなぎとご飯を一緒に 食べることで、贅沢な味わいが楽しめます。
5. 名古屋おでん:

愛知県では「名古屋おでん」として知られる独自のおでんがあります。薄口醤油ベースの出汁に、こんにゃくやちくわ、卵などが 入り、具材も多種多様です。寒い季節には特におすすめです。

これらの名古屋飯は、それぞれ異なる魅力があり、名古屋を訪れる際にはぜひ試してみてください。...

名古屋おでんなんてあったかな?とは思いましたが(しかも味噌が使われていないし)、思ったよりはいい回答でした。

てことで、こいつのRAG版をやってみました。

なお、環境構築もコードもデータも、以下の記事のものをそのまま使ってます。

大規模言語モデル「ELYZA-7b」と自作小説「計算士と空中戦艦」で「RAG」をしてみた: EeePCの軌跡

その中で「model_path = 」の後ろを「models/Tanuki-8B-dpo-v1.0-Q4_K_M.gguf」に変えただけです。

で、質問に関しては以前の記事「ElyzaのLlama3ベースの言語モデル「Llama-3-ELYZA-JP-8B」のRAGが予想以上に賢かった件: EeePCの軌跡」と同じものを使い検証します。

では、いきなり結果を列挙します。

Q
カルヒネン曹長の恩師の名前は?

A
カルヒネン曹長の恩師の名前についてですが、文脈から判断すると、その恩師はラハナスト先生である可能性が高いです。ラリヴァ ーラ少佐やエクロース准将との会話の中で、ラハナスト先生が計算術を教えた人物として言及されています。したがって、カルヒネン曹長の恩師の名前はラハナスト先生であると推測されます。

Q
イーサルミ王国はなぜオレンブルク連合皇国と戦争をすることになったのですか?

A
イーサルミ王国がオレンブルク連合皇国と戦争を始めた理由は、主に以下のような背景があります。まず、現皇帝の即位後に圧政が 敷かれ、高い税負担や言論統制、駐留軍による暴挙などが行われたことが挙げられます。これにより、イーサルミ王国内で不満が高まり、独立を求める動きが強まりました。

さらに、オレンブルク連合皇国は富国強兵策の一環として軍事力を増強しており、その影響でイーサルミ王国に対する圧力が増しました。特に、ヘリウムという重要な資源を独占していたことが、オレンブルク軍にとって大きな負担となっていました。このヘリウム不足が連合皇国側にも影響を及ぼし、最終的には水素への転換を余儀なくされました。

また、オレンブルク連合皇国は広大な湿地帯と山脈に囲まれており、陸路での侵攻が困難でした。そのため、イーサルミ王国に対する直接的な攻撃が難しくなり、結果として奇襲や海上封鎖などの手段を取ることになりました。

これらの背

Q
イーサルミとオレンブルクの戦いは、この先どうなると思いますか?

A
イーサルミとオレンブルクの戦いについて、今後の展開を予測するためには、いくつかの要素を考慮する必要があります。以下にス テップバイステップで回答します。

### 1. 現在の状況分析
- オレンブルク軍の圧政: 現在、オレンブルク皇国は圧政を敷き、ヘリウム採取井戸を独占しています。これが連合皇国にとって大きな経済的負担となっています。
- イーサルミ王国の反撃: イーサルミ王国は独立を宣言し、オレンブルクに対して反攻を開始しました。特にヘリウム採取井戸の確保が重要です。
- 戦闘の激化: 両軍ともに激しい戦闘を続けており、塹壕戦や機関銃による射撃が続いています。

### 2. 国際情勢と外交
- フロマージュ共和国の仲介: 連合皇国とイーサルミ王国の間で和平交渉が進んでいることが示されています。これは重要な転機となり得ます。
- 他国の影響: 他の列強諸国や国際機関がこの戦争にどのよう

ご覧いただくと、それほど回答精度は悪くありません。
が、気になる点はたった一つ。
それは「回答が途切れてしまう」問題です。
これは、ELYZA-JPのggufでも同じでした。ある一定以上の文字数を吐き出してはくれないんですよね。
パラメータをいじったり、それ用のものがないか探したりしたんですが、文字数については増やしようがありませんでした。

このために8ビット版も試したんですが、あまり精度向上も文字数アップも見られず。

特にこのTanuki-8Bというモデルは、長文の回答を返したがります。にもかかわらず、文字数が解けない。

量子化モデルでは、ダメなんですかねぇ。

ちょっとした回答をさせる分には悪くないモデルです。それどころか、最後の質問なんて結構いいとこ突いてます。この先が、知りたかった。

これの回答文字数を増やす手段がわかれば、多分、最強のローカルLLMによるRAGが構築できそうです。


LLMのファインチューニングとRAG ?チャットボット開発による実践?

2024年9月 2日 (月)

純日本産なローカルLLM「Tanuki-8B」を試してみた

個人的にはELYZA-JPがLLMとして結構お気に入りとなってますが、あちらはMeta社のLlama3をベースに作られたものでした。
これに対し、こ子で紹介するTanuki-8B(さらに大規模版のTanuki-8X8B)はゼロから新たな別プロセスで作られたLLM(大規模言語モデル)とのことです。
ということで、以下を参照して、さっそく試してみます。

weblab-GENIAC/Tanuki-8B-dpo-v1.0 · Hugging Face

で、実行するコードは以下。


from transformers import AutoModelForCausalLM, AutoTokenizer, TextStreamer

model = AutoModelForCausalLM.from_pretrained("weblab-GENIAC/Tanuki-8B-dpo-v1.0", device_map="auto", torch_dtype="auto")
tokenizer = AutoTokenizer.from_pretrained("weblab-GENIAC/Tanuki-8B-dpo-v1.0")
streamer = TextStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)

messages = [
    {"role": "system", "content": "以下は、タスクを説明する指示です。要求を適切に満たす応答を書きなさい。"},
    {"role": "user", "content": "おすすめの名古屋飯を5つ教えてください。"}
]

input_ids = tokenizer.apply_chat_template(messages, add_generation_prompt=True, return_tensors="pt").to(model.device)
output_ids = model.generate(input_ids,max_new_tokens=1024,temperature=0.5,streamer=streamer)

必要なライブラリですが、Pytorch(GPU版)、Transformers、acceralate辺りは最低必要かと。バージョンに関しては特に指定がなさそうなので、そこそこ最新版ならいいのではと思います。

これを「tanuki-8b.py」として保存。
なお、質問分は上の「"user", "content": 」の後の" "区切り部分に書き込みます。で、あとはプロンプトを開き、このコードを保存したフォルダにcdコマンドで移動し、

> python tanuki-8b.py

と入力してやれば実行されます。

なお、上のモデルは量子化されていないモデルのため、結構重いです。が、その分、精度は高め。
ちなみにgguf版も落として試してみたんですが、8ビット量子化したものでもなんか支離滅裂な動きだったので、今回はこちらのみを試します。

なお、動作の感じですが、以下のように文字を小出しにしてくる感じの動きをします。
最後にドバッと出されるより、動いてる感はありますね。

Tanuki8b_01

では早速、質問を投げかけてみます。
ELYZA-JPの時と、ほぼ同じような質問を投げてみました。
(ELYZA-JPの場合は、ローカルLLM「Llama-3-ELYZA-JP-8B」にいろいろ聞いてみた: EeePCの軌跡を参照)

Q:
おすすめの名古屋飯を5つ教えてください。

A:
名古屋飯は独特で美味しいものがたくさんありますので、いくつかおすすめをご紹介します。まず一つ目は「ひつまぶし」です。これはうなぎの蒲焼を細かく刻み、ご飯に乗せて食べる料理で、特製のだしや薬味と一緒に楽しむことができます。次に、「味噌カツ」も外せません。甘辛い味噌ダレがたっぷりかかったカツで、ご飯やキャベツと一緒に食べると絶品です。

三つ目に「きしめん」を挙げます。平たい麺が特徴で、つゆに浸して食べることで、つるつるとした食感が楽しめます。特に寒い季節には温かいつゆが体を温めてくれます。四つ目は「天むす」です。エビや野菜を酢飯と一緒におにぎり状に握ったもので、手軽に食べられる一品です。最後に「味噌煮込みうどん」もおすすめです。濃厚な味噌スープと太麺が絶妙にマッチし、寒い季節にぴったりの一品です。

これらの名古屋飯は、それぞれ独自の魅力があり、一度試してみる価値があります。名古屋を訪れる際には、ぜひ地元の味を楽しんでみてください。

加工なしで、この回答です。割と正確な情報を返してきました。ELYZAの時は瀬戸焼きそばとか出てきましたから。

なお、この時のタスクマネージャーは以下の通りでした。
(GPUメモリーは6.5GBほど使ってました)

Tanuki8b_02

これだけの回答を出すのに、4、50秒といったところでしょうか。
これを実行したのはRTX4060搭載の新ゲーミングノートですが、さすがに量子化されていないモデルは重い。

では、次の質問。

Q:
月島の名物と言えばなんでしょうか?

A:
月島の名物として特に有名なのは「月島もんじゃ」です。月島は東京都中央区に位置し、もんじゃ焼きの発祥地として知られています。このエリアには多くの専門店があり、新鮮な海産物を使ったもんじゃ焼きを楽しむことができます。特に「月島もんじゃストリート」と呼ばれる通りには、多くの老舗や新しい店が軒を連ねており、観光客にも地元の人々にも愛されています。また、月島には他にも寿司や天ぷらなどの和食も豊富で、グルメスポットとしても魅力的です。

特に「東京」とは書いてませんが、東京の月島だと認識してくれました。

Q:
部下のやる気を上げるための施策を5つ教えてください。

A:
部下のやる気を引き出すためには、いくつかの戦略を組み合わせることが効果的です。まず第一に、明確な目標設定とフィードバックの提供が重要です。部下が自分の役割や期待される成果を理解できるようにし、定期的に進捗を確認し、具体的なフィードバックを行うことで、成長の実感を持たせることができます。

次に、キャリア開発の機会を提供することも大切です。スキルアップのための研修やセミナーへの参加、メンター制度の導入などを通じて、部下が自己成長を実感できる環境を整えます。これにより、長期的なモチベーションが向上します。

また、適切な報酬と認識も欠かせません。金銭的なボーナスだけでなく、表彰や感謝の言葉、特別な休暇など、多様な形で努力を認めることで、部下は自分が組織にとって重要な存在であると感じるようになります。

さらに、職場環境の改善も重要です。オープンなコミュニケーションを促進し、チームワークを強化するためのミーティングやブレインストーミングセッションを定期的に開催することで、部下が意見を出しやすい雰囲気を作ります。また、柔軟な働き方やワークライフバランスを尊重することも、ストレスを軽減し、仕事に対する意欲を高める要因となります。

最後に、部下の意見やアイデアを積極的に取り入れる姿勢を示すことが大切です。上司として、部下の声に耳を傾け、彼らの意見が実際の業務改善や新しいプロジェクトに反映されるようにすることで、自分が尊重されていると感じさせることができます。これにより、部下は自分の意見が組織に影響を与える力を持っていると感じ、さらなる努力を惜しまなくなるでしょう。

これらの施策を組み合わせることで、部下のやる気を効果的に引き出すことができます。

割と一般論的な答えが返ってきますが、ELYZA-JPでは方策名が主(1on1をやる、など)なのに対し、こちらは一つ一つが具体的で長いですね。

Q:
今後、生成AIを活用する方法として、どのようなものが ありますか?

A:
今後、生成AIを活用する方法は多岐にわたります。まず、コンテンツ作成の分野では、ブログ記事、ニュース記事、マーケティング資料、クリエイティブなデザインなど、さまざまな形式のテキストやビジュアルコンテンツを自動生成することが可能です。これにより、時間と労力を大幅に節約し、高品質なコンテンツを迅速に提供できます。

また、カスタマーサポートにおいても生成AIは非常に有用です。チャットボットやバーチャルアシスタントが顧客の問い合わせに対して自然な対話を行い、24時間対応が可能になります。これにより、顧客満足度が向上し、サポートコストも削減されます。

さらに、教育分野でも生成AIは大きな変革をもたらします。個別学習プランの作成や、学生の理解度に応じたカスタマイズ教材の提供が可能となり、教育の質と効率が向上します。また、教師の負担を軽減し、よりクリエイティブな授業準備に時間を割くことができます。

医療分野でも生成AIは重要な役割を果たします。診断支援システムや治療計画の立案、患者データの解析など、多岐にわたる応用が期待されています。これにより、医療従事者の業務負担が軽減され、より質の高い医療サービスが提供できるようになります。

エンターテインメント業界でも、生成AIは新しいコンテンツの生成や既存コンテンツの改良に利用されます。映画や音楽のプロット作成、キャラクターのデザイン、ゲームシナリオの自動生成など、創造的なプロセスをサポートします。

最後に、ビジネスインテリジェンスやデータ分析においても生成AIは強力なツールです。大量のデータから洞察を抽出し、予測モデルを構築することで、ビジネス戦略の立案や意思決定をサポートします。これにより、競争力を維持・向上ため、全体的な効率が向上します。

このように、生成AIはさまざまな分野で革新的な変化をもたらし、私たちの生活や業務をより便利で効率的にする可能性を秘めています。

ELYZA-JPでもさほど悪い答えではなかったですが、こちらは文章が長めで具体的ですね。

こんな具合に、普通に使う分にはそん色のないモデルだと分かります。全体的に言えることは、一文が長くて、分かりやすく具体的な説明を試みている辺りでしょうか。そこは、好感持てます。

が、これを本格的に使うには、やはりRAGができないと、ですね。
そのやり方は、gguf版だったらすぐにできたんですが、あちらがあまりにも挙動不審だったので、もっと安定したものが出てきたら考えます。


60分でわかる! 生成AI ビジネス活用最前線

2024年7月24日 (水)

東京のセールスフォースに行ってきました

なんか、出張が続きます。

今日は、東京に行ってきました。

Img_5400

富士山は割とよく見えました。

Img_5402

いつもなら朝から行くことが多いんですが、今回は昼の14時半ごろに到着。

Img_5410

行先はこちら。セールスフォースという会社です。
ここでTableau(タブロー)というツールに関するセミナーがあり、そこに参加いたしました。
タブローなどというと、なんだか誰かの名前のようですが、データ分析・可視化を行うBI(ビジネスインテリジェンス)ツールのことです。

Img_5412

なお、すぐ横は皇居です。大手町駅のすぐそばだったので、ごらんのとおり堀と橋が見えます。

Img_5413

今回、意外とSurface Go 3が役に立ちました。結構メモしてました。iPad miniにしようかと思ったんですが、こちらで正解でした。

このイベントは、要するにデジタルツールの活用事例の紹介なんですが、参加者が結構な地位の方ばかりだったため、データドリブン経営だの人材育成だのと、そこらのツール活用とは違う次元の会話が飛び交ってました。

内容については詳しくは触れませんが、個人的に得られるものは多かったイベントでした。

Img_5416

帰りは19時の東京発の新幹線で帰ったのですが、2時間半かかるので、家に着いたのは22時近くでした。

Img_5422

駅構内で、なんとなく試食したら美味かったので買ってきたのがこちら。
戦利品は、これだけですね。

そういえば、つい2日前に新幹線が不通になっておりましたが、その影響は特にありませんでした。

にしても、先日も鹿児島に行った日にクラウドストライク問題が起きて混乱が発生したばかりだというのに、最近はインフラ系の事故が多いですね。なんか、ギリギリかいくぐっている感じです。

次に東京へ行くのはいつのことやら・・・いや、実は決まっているんですが、それはまた後日。

Tableauによる最適なダッシュボードの作成と最速のデータ分析テクニック ~優れたビジュアル表現と問題解決のヒント~

2024年7月 1日 (月)

ローカルLLM「Llama-3-ELYZA-JP-8B」にいろいろ聞いてみた

ElyzaのLlama3ベースの言語モデル「Llama-3-ELYZA-JP-8B」のRAGが予想以上に賢かった件: EeePCの軌跡」の記事で、いきなりRAGから入ってみましたけど、そもそも「Llama-3-ELYZA-JP-8B」自体の実力はいかほどか?を試してませんでした。
ということで、素のLlama-3-ELYZA-JP-8Bの実力を試してみます。

で、そのコードはこちら。

import sys
from llama_cpp import Llama
llm = Llama(model_path="models/Llama-3-ELYZA-JP-8B-q4_k_m.gguf",
            n_gpu_layers=-1,
            verbose=False,
            )
output = llm("<user>\n" + sys.argv[1] + "\n<assistant>\n", max_tokens=512)
print(output['choices'][0]["text"] + "...")

これを「elyza_ggufllm3.py」という名前で保存しました。
RAGを使わないと、こんなに短くて済むんですね。
なお、環境設定は前記事を参照、量子化したモデルについても前記事同様、以下の「Files and versions」からダウンロードします。

elyza/Llama-3-ELYZA-JP-8B-GGUF · Hugging Face

使い方ですが、実行プログラムの後ろに質問文をつけるスタイルです。例えば、

> python elyza_ggufllm3.py お勧めの名古屋飯を教えてください。

という具合です。ちなみに、回答はうちのメインPCの場合、だいたい30秒ほどで返ってきました。

名古屋飯と言えば、独特の文化や歴史が育んできた食事スタイルです。名古屋で長く愛されている代表的な名古屋飯をいくつかご紹介します。

1. 名古屋コーチン親子丼:名古屋の地鶏「名古屋コーチン」は、卵を産むメスと雄を分けることで、脂肪が少なく肉質がきめ細かい特徴があります。親子丼は、タレに漬け込んだ親鳥と新生卵の黄身をどんぶりで提供します。
2. 手羽先天むすび:名古屋コーチンや地元の鶏肉を使った手羽先を、てんむす(手毬寿司)風に握っています。サクッと揚がった手羽先の食感と味わいは、名古屋のソウルフード。
3. 小倉トースト:小倉という名前に反して小豆は使われず、カステラやバターを使用したトーストです。愛知県民は長年この甘くて香ばしいトーストを朝食に食べることが多くあります。
4. 味噌カツサンド:味噌を付けることで名古屋風のアレンジがされた、名物の豚カツです。味噌とパンは意外にも合う組み合わせで、地元では人気の軽食。
5. 瀬戸焼きそば:瀬戸市に本社があるイタリアンレストラン「モリ・パニーニ」が創業したお店です。麺を焼くスタイルは新しい名古屋飯として若い人々からも支持されています。

これらの名古屋飯は、地元の人々の生活や文化に根付いた食事スタイルを表現しています。名古屋に訪れた際には、是非とも味わってみてください!

これが、回答文。なんかすごくないですか?たかが5GB未満のモデルですよ、これ。ただし、最後のやつがちょっと微妙。瀬戸焼そばが名古屋飯?うーん、惜しい。

調子に乗って、こんなことも聞いてみます。

Q : 月島の名物と言えばなんでしょうか?

「江戸前エルフ」にハマってたので、つい聞いてみました。

月島は、東京都中央区にありますが、「もんじゃ焼き」が有名です。月島は「もんじゃ焼き発祥の地」としても知られていて、多くのもんじゃ焼き店があります。もんじや焼きと呼ばれる小麦粉を用いた生地を鉄板で焼き、各種具材をトッピングして作るこの料理は月島が発祥であり、現在でも観光客や地元の人の人気を集めています。

東京というメジャーどころなためか、こちらはかなり正確な模様です。

さて、職場の活性化にお悩みなマネージャーっぽいことも聞いてみます。

Q : 部下のやる気を上げるための施策を5つ教えてください。

人間ならば答えにくい質問です。どんな回答が返ってくるか?

部下のやる気を上げるための施策は、以下の5つです。

1. 目標設定とフィードバック:
* 個人やチームに明確な目標を設定し、達成に向けてのプロセスを共有する。
* 定期的に進捗状況や結果に対してフィードバックを与え、改善点や成功要因を分析する。
2. 自主性と裁量権:
* 部下にできる限り任せて、自主性と裁量権を与えることで、モチベーションが向上し、主体的に仕事に取り組むことができる。
* 支援やサポートは必要に応じて提供する。
3. 成長機会の提供:
* 新しいスキルや知識の習得の機会を与えることで、部下の成長意欲を高める。
*外部研修やトレーニングプログラムなどを活用し、能力向上を目指す。
4.報酬とインセンティブ:
* 部下が仕事に取り組む動機付けとして、報酬やインセンティブを与えることが有効。
* 報酬の内容や方法は個人のタイプや好みに応じて選択する。
5.職場環境とコミュニケーション:
* 職場環境を整備し、部下が快適に仕事できるようにする。
*定期的に1on1ミーティングやチーム会議を開催して、コミュニケーションを促進し、部下の意見や要望を聞く。

これらの施策は、部下のやる気を上げるために有効ですが、個人のタイプや組織文化に応じて調整する必要があります。

わりと正論が返ってきました。1on1ミーティングが出てくるあたり、今どきの知識です。
でも、これができる上司ならば、最初から悩むことはないんじゃないか?という声も聞こえてきそうで・・・

ところで、このような生成AIをどう活用すればよいか悩まれている方も大勢います。直接、彼自身に聞いてみましょうか。

Q : 今後、生成AIを活用する方法として、どのようなものが ありますか?

で、そんなAI自身が答えたソリューションは以下。

生成AIは、多くの分野で応用が期待されており、以下にいくつかの例を示します。

1. **Chatbotsと自動化】: 生成AIの能力を使用して、チャットボットや会話型のアプリケーションを作成し、顧客サポートや問い合 わせに答えることができます。
2. **コンテンツ作成支援」:** 記事執筆、ソフトウェアドキュメントの自動生成、翻訳など、生成AIが人間の創造性を補助すること ができます。
3. **データ分析と可視化」:** 生成AIを使用して、複雑なデータセットから新しいインサイトやパターンを見つけることができたり 、可視化された結果を提供することができます。
4.「デザインの自動化」:** 設計、イラストレーション、ビジュアルエフェクトなどで生成AIを使用して、デザイナーの創造性を補助したり、自動化することができます。
5.「プログラミングとコード生成」:** 生成AIが自動的にコードを生成し、開発プロセスを高速化や生産性の向上などを実現することができます。
6.「アートとエンターテイメント」:** 様々な形式で生成した作品は、人々に新しい体験を提供する可能性があります。例えば、音楽や小説、映像などでの使用が想定されます。

上記は一例です。生成AIの能力は多岐にわたるため、将来的には、多くの分野で活用されることが期待されています。

3つ目以降は、ちょっとこのモデルでは無理なものも含まれてますね。ですがまあ、いいとこついているんじゃないでしょうか?

ローカルPC上で動く、モデルサイズが5GBにも満たない生成AIからの回答と思うと、なかなかすごいんじゃないですか。

つい1年前には、以下の記事にあるようなレベルだったんですが。

りんなチャットAI「rinna japanese-gpt-neox-3.6b」と楽しく??会話してみたら……: EeePCの軌跡

わりと的外れな会話で、当時はそれでも感動してましたけど、たった1年でこの進化です。

さらに1年後には、どれくらい発達しているんでしょうかね?


ご当地グルメコミックエッセイ まんぷく名古屋

2024年6月27日 (木)

ElyzaのLlama3ベースの言語モデル「Llama-3-ELYZA-JP-8B」のRAGが予想以上に賢かった件

昨日(6/26)に、東大発ベンチャーであるELYZA(イライザ)からLlama3ベースの言語モデル「Llama-3-ELYZA-JP」が発表されました。

「GPT-4」を上回る日本語性能のLLM「Llama-3-ELYZA-JP」を開発しました|ELYZA, Inc.

つい先日、Googleの大規模言語モデルを使った「notebookLM」に圧倒されたばかりですが、オープンモデルのELYZAも気になるので、試してみることにしました。

なお、GPT-4を超えたとされるのは、ELYZA‐JPの70Bモデル(700億パラメーター)であり、こちらはモデルとしては配布されておらず、APIとしての利用のみとなっている模様。
公開されているのは8Bモデル(80億パラメーター)のみです。

以前のLlama2ベースの時は、7Bと13Bの2種類が公開されていたのに、今回は8Bのみとは・・・などと残念に思ってましたが、むしろこの8Bモデル、以前の13Bモデルよりも高精度な言語モデルでした。

実際、8Bモデルでも日本語での性能はGPT-3.5 Turbo並みだというので、なかなか大したものです。

それの量子化モデルを入手し、以前の記事、

大規模言語モデル「ELYZA-7b」と自作小説「計算士と空中戦艦」で「RAG」をしてみた: EeePCの軌跡

でやったRAGにトライしてみました。
なお、環境設定その他は上の記事の時そのままです。

モデルを、以下のサイトからダウンロードします。

elyza/Llama-3-ELYZA-JP-8B-GGUF · Hugging Face

ここのサイトの「files and versions」タブをクリックし、「Llama-3-ELYZA-JP-8B-q4_k_m.gguf」の横の下矢印をクリックしてダウンロードを実行します。

得られたモデル「Llama-3-ELYZA-JP-8B-q4_k_m.gguf」を、先のフォルダの「models」に入れておきます。

プログラムコードも先の記事ほぼそのままですが、一か所、「model_path = 」のところを、

model_path = f"models/Llama-3-ELYZA-JP-8B-q4_k_m.gguf"

としました。このコードを、

> python elyza_rag.py

と実行すると、前記事同様、RAGが実行されます。

では、前回と同じ質問を投げかけてみます。

##Question: カルヒネン曹長の恩師の名前は?

その返答はというと、

カルヒネン曹長の恩師の名前は、ラハナスト先生です。

となりました。Llama2-7Bモデルではそっけなく「ラハナスト」としか答えなかったところを見ると、かなり人間的になりましたね。

ちなみに、8Bモデルということもあり、かなり軽いです。うちのGTX1650Tiを使っても、30秒ほどで回答が返ってきます。
(起動時は相変わらず遅い)

調子に乗って、もう少し高度な質問をしてみます。

##Question: イーサルミ王国はなぜオレンブルク連合皇国と戦争をすることになったのですか?

これ、Llama2のモデルでは支離滅裂な回答しか返ってこなかったのですが、Llama3ベースの今度のモデルは違います。

イーサルミ王国は、オレンブルク連合皇国の属国であったが、現皇帝が即位してから圧政を敷き、高い税負担や言論統制などを行ったため、イーサルム王国内は大いに乱れた。さらに、強大化した軍隊が属国への干渉を働くこととなり、悪循環を招いた。そこで、イーサルミ王国は連合皇国からの独立を宣言し、オレンブルク連合皇国軍に対して奇襲を行い、これを一斉排除することに成功したが、その後、苛烈な独立戦争が始まった。

ちゃんと、文脈を捉えた回答が返ってきました。これは予想外でした。
Llama3ベースのモデルって、優秀過ぎない?

もちろん「notebookLM」あたりと比べたらまだまだでしょうけど、やっすいゲーミングPC上で実行していることを思えば、これはなかなかの性能です。

てことで、さらに調子に乗って、より突っ込んだ質問をしてみました。

##Question:イーサルミとオレンブルクの戦いは、この先どうなると思いますか?

この物語の先を予想させてみました。文脈を読んで、彼(Llama3-ELYZA-JP)はなんと回答するのか?

銃が飛ぶように売れては犯罪の誘発などにつながって困りものだが、計算尺なら飛ぶように売れたところで誰も困らない」という会話から、イーサルミ王国とオレンブルク連合皇国の戦争が長期化していることがわかります。

また、「我々の独立を承認することは他の王国の独立を誘発しかねないと考えている」や「多数の国が連合する皇国にとって、それらの国の離脱が最も恐れるべき事態だ」という会話から、オレンブルク連合皇国はイーサルミ王国の独立を認めるつもりはないことがわかります。

さらに、「我々は決して屈しない。やつらが我が国の独立を認めるまで、我々は戦い続ける」という会話から、イーサルミ王国は独立するために戦争を継続する意思があることがわかります。

以上の情報から、イーサルミ王国はこの先もオレンブル

なんか、最後はちょっと途切れてしまいましたが、要するにオレンブルクとイーサルミの戦争はまだまだ続くと言いたかったのでしょう。そういう流れの回答です。
ただし、この回答ばかりは80秒ほどかかりました。かなり頭?を使ったようです。ですが、使っただけの回答です。恐れ入ります。

ということで、予測的なことまで可能となったLlama3ベースの8BモデルによるRAGは、なかなか使えそうです。

今回は「計算士と空中戦艦 : 小説家になろう 」の第1章のみでしたが、第2章まで読み込ませて、より突っ込んだ質問をしてやりたいですよね。


面倒なことはChatGPTにやらせよう (KS情報科学専門書)

2024年6月24日 (月)

Googleの生成AI「Gemini 1.5 Pro」を使ったサービス「notebookLM」がすごいらしいので試してみた

GoogleがOpenAIのGPT 4に対抗して「Gemini 1.5 Pro」という生成AIを作っているということは知ってましたが、これの使いどころを知りませんでした。
が、最近、このGemini 1.5 Proを使った「notebookLM」というサービスがあることを知ったので、早速使ってみました。

NotebookLM | Note Taking & Research Assistant Powered by AI

20240623-193057

上のサイトで「Try notebookLM」をクリックします。
Google ChromeでGoogleアカウントにログイン済みならば、いきなり入れるはずです。

さて、このnotebookLMですが、OpenAIのChatGPTの最新版(GPT-4o)と比較して、いくつかメリットがあります。

・ 扱えるコーパス量が多い
・ 日本語の精度についてはGPT-4o以上

これはGoogleのひとから聞いたのですが、コーパスがChatGPTに比べてかなり多いとのことです。
コーパスが多いというのは、つまり大量の文章を処理できるということ。RAGでも使わない限り、通常のGPTならば数千文字程度しか一度に読み込んでくれないので、これは大きい。
地味に日本語読解力が強いというのもありがたいことです。

さらに、期間限定ですが、

・ 今なら無料で試せる

というところが一番大きいかと。

ということで、「大規模言語モデル「ELYZA-7b」と自作小説「計算士と空中戦艦」で「RAG」をしてみた: EeePCの軌跡」の際に使用したテキストファイルを使って、いろいろとやらせてみました。

Try notebookLMをクリックすると、以下のような画面が出てきます。

20240623-193116

まずは、

計算士と空中戦艦 : 小説家になろう

の第1部 全19話、約11万文字のテキストを一つにまとめておきます。

この前準備をした後に、「新しいノートブック」をクリック。

20240623-193128

こんなのが出てきます。
で、今回はテキストファイルなので、「テキストファイル」を選択して、先ほど準備したテキストファイルを選びます。

20240623-190644

しばらく読み込んだ後に、概要や質問の候補などが表示されます。
この時点で、驚くほど正確に内容把握していることが分かります。

これは期待大。

ということで、先日のRAG以上の質問を投げかけてみました。

Q:この物語の概要を教えてください。

上にも概要が出てますが、改めて聞いてみました。すると、

物語のあらすじ

 この物語は、イーサルミ王国とオレンブルク連合皇国の戦争を描いています。

●主人公: ユリシーナ・カルヒネン曹長は、イーサルミ王国空軍所属の砲術計算士です。3年前にオレンブルク連合皇国の空襲で家族を失い、復讐のため計算士の道を選びました。
●イーサルミ王国: ヘリウム採掘場を独占する資源の豊かな国。オレンブルク連合皇国からの独立を宣言後、3年間戦争が続いています。
●オレンブルク連合皇国: 資源の乏しい国で、イーサルミ王国を属国としようと侵攻を続けています。ヘリウム不足のため、危険な水素を空中戦艦に使用しています。
●空中戦艦: 物語の舞台となる空中戦艦は、ヘリウムガスで浮遊し、大砲や爆弾を用いて戦います。主人公は「ヴェテヒネ」、「サウッコ」という名の空中戦艦に搭乗します。
●戦闘: 主人公は、卓越した計算能力で敵艦を撃沈し、イーサルミ王国空軍の勝利に貢献します。その功績により、異例の金三等勲章を授与されます。
●計算機: ラハナスト先生という計算工学の権威が、画期的な電子手順計算機を開発します。この発明は、将来、戦争のあり方を変える可能性を秘めています。
●戦争の終結: 物語終盤で両国の和平交渉が始まりますが、ヘリウムの供給を巡る対立などから、交渉は難航が予想されます。

 主人公は、戦争の悲惨さを目の当たりにしながらも、計算士としての職務を全うし、祖国の勝利のために戦い続けます。物語は、戦争の終結を予感させつつも、新たな戦いの始まりを予感させながら幕を閉じます。

予想以上に、詳細なあらすじが返ってきました。
書いた本人なので分かりますが、かなり正確ですね、これ。

となれば、こんな質問もしたくなります。

Q:この物語の続きとして、どのような展開が考えられますか?

物語の続きを考えさせてみました。
で、返ってきたのは以下の答え。

物語の今後の展開の可能性

 今回の物語の続きとして考えられる展開は、新たに発生したオレンブルク軍の動きと、主人公たちの動向、そして戦争の終結に関する点に集約されます。

●新たな敵の出現: 主人公たちが所属するイーサルミ王国空軍は、偵察艦撃沈後、オレンブルク軍の動きがないことに不気味さを感じています。
 これは、嵐の前の静けさであり、オレンブルク軍が何か大きな作戦を企てている可能性を示唆しています。
 具体的な展開としては、これまで登場していない新型の空中戦艦や、新たな戦術を引っ提げての攻撃などが考えられます。
 主人公たちのこれまでの活躍により、オレンブルク軍も戦術の見直しを迫られている可能性があります。
●主人公たちの次の戦い: 主人公であるカルヒネン曹長は、新しい計算尺を入手し、それを試す機会を待ち望んでいます。
 次の戦いでは、この新しい計算尺を用いて、これまで以上の精度で敵艦を攻撃することが予想されます。
 また、物語終盤でエクロース准将が、人命を損耗しない兵器として、計算機に爆弾を積んで突撃させる構想を語っています。
 この発言は、今後の戦争の行く末を示唆しており、主人公たちの前に、計算機を兵器として利用しようとする新たな敵が立ちはだかる可能性も考えられます。
●戦争の終結: イーサルミ王国とオレンブルク連合皇国の間で和平交渉が始まったことが語られています。
 しかし、両国の主張は大きく異なっており、交渉が決裂する可能性も高いです。
 特に、ヘリウムの供給を巡って対立が深まる可能性が示唆されています。
 もし交渉が決裂した場合、戦争はさらに激化し、主人公たちもより危険な戦いに巻き込まれることが予想されます。
 主人公たちの活躍が、和平交渉の行方にも影響を与える可能性も考えられます。

 これらの要素を組み合わせることで、様々な展開が考えられます。例えば、和平交渉が続く中で、新たな敵が現れ、主人公たちがその戦いに巻き込まれるという展開や、和平交渉が決裂し、全面戦争に突入する中で、主人公たちが重要な役割を果たすという展開などが考えられます。

実は第2部(全16話)がすでに書き上げられてますが、特に1つ目、3つ目については確かに第2部の中で描かれてます。
なかなか賢いですね、これ。

では、さらに突っ込んだ質問を。

Q:現実世界での第一次世界大戦を参考に、この物語を広げるとしたならば、どのような展開が考えられますか?

創作と現実世界を掛け合わせた回答を求めてみました。さあ、どう答える!?

 現実世界での第一次世界大戦を参考に、物語をどのように広げられるかについて、ソースからは断定的な情報は得られません。
 しかし、いくつかの手がかりはソースから見つかります。

●新兵器の登場: 現実の第一次世界大戦では、戦車や毒ガスなど、それまでの戦争の常識を覆す新兵器が登場しました。
 ソースでは、電子手順計算機という画期的な計算機が登場します。
 これは、現実世界のコンピュータの原型ともいえる発明であり、戦争のあり方を大きく変える可能性を秘めています。
 今後、この電子手順計算機が兵器に応用され、新たな戦術や戦略が生まれる展開が考えられます。
●情報戦の激化: ソースでは、敵の偵察艦の動きが活発化し、主人公たちが所属するイーサルミ王国空軍も、偵察艦の撃沈に成功しています。
 現実世界の第一次世界大戦でも、航空機による偵察や、無線通信の傍受など、情報収集の重要性が高まりました。
 この物語においても、電子手順計算機を駆使した暗号解読や、敵の行動予測など、情報戦が激化する展開が考えられます。
●多国籍軍の編成: ソースでは、イーサルミ王国はフロマージュ共和国から空中戦艦の技術供与を受けています。
 現実世界の第一次世界大戦でも、複数の国が同盟を組んで戦いました。この物語においても、フロマージュ共和国が軍事介入したり、新たな国が参戦したりする可能性があります。
●戦線の膠着: 現実世界の第一次世界大戦では、塹壕戦と呼ばれる長期にわたる戦線膠着状態が生じました。
 ソースでも、イーサルミ王国とオレンブルク連合皇国の戦争は3年間続いており、キヴィネンマー要塞周辺などでは塹壕戦が行われています。
 今後、物語の中でも、戦線が膠着し、長期戦に突入する展開が考えられます。
●厭戦気分の高まり: 現実世界の第一次世界大戦では、長期化する戦争によって、国民の間で厭戦気分が高まりました。
 ソースでは、主人公の同僚であるマリッタが「さっさと終わらせてほしい」と戦争に対する本音を漏らしています。
 今後、物語の中でも、戦争の長期化によって、兵士や国民の間で厭戦気分が高まり、和平を求める声が大きくなる可能性があります。

 これらの要素を組み合わせることで、現実世界の第一次世界大戦を参考に、物語をより複雑化・多層化することが可能になると思われます。ただし、これらの展開はあくまでも可能性であり、実際に物語がどのように展開するかは、作者の判断によります。

なかなかどうして、現実知識を上手く取り混ぜながら、物語の世界観を継承しつつ今後の展開予測を描いています。
では、もうちょっと細かい質問も投げてみます。

Q:電子手順計算機の発明は、戦争にどのような影響を与える可能性がありますか?

この物語では、かなり初期の電子計算機が登場します。これの与える影響についても聞いてみました。
で、回答ですが、

 提供された情報源では、電子手順計算機の発明が戦争にどのような影響を与える可能性があるかについては明確に述べられていません。
しかし、これらの情報源は、計算尺や計算工学の重要性、そしてそれが戦争においてどのように利用されているかについて詳しく説明しています。
 例えば、計算士は計算尺を用いて敵の進路予測や弾道計算を行い、戦争の勝敗に大きく貢献しています。 また、電子手順計算機は従来の計算尺よりも高速かつ正確に計算を行うことができ、将来的には人間の役割を担う可能性も秘めていることが示唆されています。

こちらも、現実世界と合わせた答えを出してきました。

まあ、ひと言で言って「凄い」ですね。
当然と言えば当然ですが、オープンモデルの7b(70億パラメータ)モデルなんて、歯が立ちません。
やっぱり、大規模も大規模な言語モデルだけあって、強烈です。

ちなみに、まだGPT-4oは触ったことはないですが、あちらもきっと強烈なんでしょうね。
ですが、こちらは無料でここまで使えてしまうという点で、圧倒的です。

いずれは有料サービスに切り替わるはずですが、今はまだ無料。

最新の生成AIに触れてみたいという方は、ぜひこの機会にお試しあれ。


生成AIプロンプトエンジニアリング入門 ChatGPTとMidjourneyで学ぶ基本的な手法

2024年6月21日 (金)

大量の画像ファイルからOpenCV使って特定の顔が映ってる写真だけを抜き出すやつを作った

タイトルの通りです。必要性に迫られて、ある顔が映っている画像ファイルを選別して抜き出すやつを作ってみました。
長男の卒業式写真をもらったんですが・・・約740枚もあって、とんでもない量が送られてきました。容量も全部で11.2GB。
いやあ、いくらなんでも740枚は多過ぎだろう。欲しいのは、自分の子供が映っているやつだけなんだけど。
ちょっと、学校側は張り切り過ぎです。

てことで、

1.テンプレート画像となる顔画像を用意
2.740枚の画像が入ったフォルダ「data」の1枚1枚を読み込み、顔検出する
3.その検出した画像とテンプレート画像の顔をと比較し、類似度を計算
4.類似度がある一定以上の顔画像を含む画像ファイルを「result」というフォルダにコピーする

というプログラムを作りました。

いわゆるディープラーニングの画像認識を使わず、OpenCVのみとしました。なんせ、740枚も処理するので、畳み込みニューラルネットワーク(CNN)では時間がかかり過ぎです。このため、簡易な方法を選びました。

具体的には、顔検出にはhaar-like特徴分類器を、類似度計算に使う画像特徴量にはSIFT特徴を、2つの画像の特徴量のマッチングにはBFMatcher、つまり総当たりのアルゴリズムを使ってます。

で、作ったのが以下のプログラムです。
(「face_pickup.py」という名前にしました)


import cv2
import numpy as np
import os
import shutil
# 顔を検出する関数
def detect_faces(image):
    # Haar-like特徴分類器を使用して顔を検出
    face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=10, minSize=(200, 200))
    return faces
# SIFT特徴抽出器を作成する関数
def create_sift():
    sift = cv2.SIFT_create()
    return sift
# 画像の特徴量を計算する関数
def compute_features(image, sift):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    keypoints, descriptors = sift.detectAndCompute(gray, None)
    return keypoints, descriptors
# マッチングを行い、類似度を計算する関数
def match_features(des1, des2):
    bf = cv2.BFMatcher()
    matches = bf.knnMatch(des1, des2, k=2)
    good_matches = []
    try:
        for m, n in matches:
            if m.distance < 0.75 * n.distance:
                good_matches.append(m)
    except ValueError:
        pass
    similarity = len(good_matches) / max(len(des1), len(des2))
    return similarity
# メインの処理
def main():
    # 顔検出用の画像を読み込む
    face_image = cv2.imread('face.jpg')

   
# dataフォルダ内の画像を読み込む
    images_folder = 'data'
    images = [f for f in os.listdir(images_folder) if os.path.isfile(os.path.join(images_folder, f))]

    # SIFT特徴抽出器を作成する
    sift = create_sift()
    # 類似度のしきい値
    similarity_threshold = 0.065

    # 類似度の高い顔が含まれている画像をresultフォルダにコピーする
    for image_file in images:
        image_path = os.path.join(images_folder, image_file)
        image = cv2.imread(image_path)
        # 顔を検出する
        faces = detect_faces(image)

        if len(faces) > 0:
            # 顔の特徴量を計算する
            face_keypoints, face_descriptors = compute_features(face_image, sift)
            max_sim = 0.0
            similarity = 0.0
            for (x, y, w, h) in faces:
                detectface_image = image[y:y+h,x:x+w]
                image_keypoints, image_descriptors = compute_features(detectface_image, sift)
                # 類似度を計算する
                if image_descriptors is not None:
                    similarity = match_features(face_descriptors, image_descriptors)
                if similarity>max_sim:
                    max_sim = similarity
            print(image_file, ',', len(faces), ',', max_sim)
            # 類似度がしきい値以上の場合、resultフォルダにコピーする
            if max_sim > similarity_threshold:
                result_folder = 'result'
                if not os.path.exists(result_folder):
                    os.makedirs(result_folder)
                shutil.copy(image_path, os.path.join(result_folder, image_file))
    print("類似度の高い顔が含まれている画像のコピーが完了しました。")
if __name__ == '__main__':
    main()

実は、Bing Chatで作らせたんですが、エラーだらけでして、これを修正してまともに動かせるように変えてます。
ChatGPTもかなり進化してますが、なかなかそのまま使えるコードをいきなりは作ってくれませんね。

これと、顔画像を検索させたい画像ファイルを「data」というフォルダにぶち込んでおきます。
使うライブラリは、OpenCV、numpy辺りがあれば使えます。
さらに、face.jpgという名前で、検索したい顔画像を用意しておきます。

Face

ぼかしのおかげでちょっとヤバい感じの写真ですが、これがテンプレート画像です(もちろん、実際にはぼかし無しです)。

20240620-194645

フォルダ構成は以上のようになります。
プログラム本体「face_pickup.py」以外には、検索させたい画像をおさめた「data」フォルダ、抜き出した画像をおさめた「result」フォルダ、テンプレート画像「face.jpg」を用意します。
(「result」フォルダはなくても自動で作られます)

これで、準備完了。

実行は、コマンドプロンプトなどでこのプログラムの入ったフォルダに移動して、

python face_pickup.py

です。

20240620-200511

こんな感じに実行されます。ファイル名、検出された顔画像の数、そしてその中で一番高い類似度の値、の順に表示されます。

なお類似度の閾値は、プログラム中ほどにある「similarity_threshold = 0.065」の0.065の値を調整します。
これを決めるために、最初は2、30枚くらいの画像でトライした方がいいでしょう。

で、閾値を決めたら、740枚を一気に走らせます。

20240620-193504

で、出てきた結果がこれ。数分ほどで処理は完了。結果、だいたい200枚くらいが拾われました。
ですが、結構余計な画像が多いですね。顔ですらない画像も中には含まれてました。
それらを削ると、残ったのは結局100枚くらい。

さほど精度がいいとは言い難いですが、740枚から1枚1枚探ることを考えると、これでもかなりマシです。
おそらくですが、何枚かは欠落しているかと思いますが、これだけ取れれば十分かと。

最初、妻が全部見て選ぶ言ってたんですが、途中で音を上げました。
そんな妻に、Pythonの威力とやらを見せつけてやりましたよ。ほんと、OpenCVの画像処理サマサマです。

高精度なCNNを使わずとも、OpenCVだけでもここまでのことはできるんです。ご参考まで。


Pythonと深層学習による革新的な画像認識と処理の裏技~CNNとOpenCVで実現する顔認識、物体検出、画像分類のテクニック~

2024年6月16日 (日)

YOLOXで独自データを使ってモデルを作ってみた

ずっと昔にYolov3の独自データ学習をして以来、長らく物体検出手法の学習を試してませんでした。
が、業務上、新しい物体検出を使って独自データでの学習をする羽目になったため、久しぶりにやってみることにしました。

ここで使う手法はYOLOX、またアノテーションツールには「VoTT」を使います。

なお、YOLOXの独自データの学習にはGPUが必須、CUDAのインストール、PytorchもGPU版が必要です。

(0) YOLOXのダウンロード、前準備、動作確認

まずは、これを入手しておきましょう。
今回使うのは、以下のサイトから入手するYOLOXです。

GitHub - Megvii-BaseDetection/YOLOX: YOLOX is a high-performance anchor-free YOLO, exceeding yolov3~v5 with MegEngine, ONNX, TensorRT, ncnn, and OpenVINO supported. Documentation: https://yolox.readthedocs.io/

Windowsなら、「<>Code」をクリックして「Download ZIP」を選択すると、ZIPファイルがダウンロードされます。
これを解凍し、適当なフォルダに入れておきましょう。
(我が家では「C:\linux」というフォルダの直下に「YOLOX-main」として入れました)

まずはこれを使えるようにします。

Windows PowerShellを開き、「cd c:\linux\YOLO-main」と入力して上のフォルダに入ります。

我が家では「大規模言語モデル「ELYZA-7b」と自作小説「計算士と空中戦艦」で「RAG」をしてみた: EeePCの軌跡」の記事にある通り、CUDA 12.1を入れてあるので、

pip install torch==2.2.1 torchvision==0.17.1 torchaudio==2.2.1 --index-url https://download.pytorch.org/whl/cu121

と、PytorchのCUDA 12.1版を入れておきました。

それ以外にも、

numpy
opencv_python
loguru
tqdm
torchvision
thop
ninja
natsort

tabulate
psutil
tensorboard

辺りのライブラリも入れてください。
他にも「pycocotools」をインストールしなきゃならないんですが、これを入れるには「VS Build tools 2022」が必要です。

Microsoft C++ Build Tools - Visual Studio

(インストール方法は、「大規模言語モデル「ELYZA-7b」と自作小説「計算士と空中戦艦」で「RAG」をしてみた: EeePCの軌跡」の前準備を参照)

ついでに、環境変数に以下の設定を入れてください。

下の「検索」で「環境変数」とやると、環境変数の設定窓が開けるので、そこにあるPath

C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.39.33519\bin\Hostx64\x64
C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\Common7\IDE

を加えます。

また、「LIB」という変数を作成し「C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.39.33519\lib\x64; C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\ucrt\x86; C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\x86」を記入。

INCLUDE」という変数には「C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.39.33519\include; C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\ucrt

と入れておきます。

(時期や環境によっては、2022や14.39.33519の数値が違うことがあります。Program Filesの中を確認し、それぞれの環境に合わせたフォルダ名を記入してください)

これをやらないと、先の学習時にエラーが出ます。

あと、YOLOX-mainの中に「setup.py」があるんですが、これは実行しないでください。
何かと不具合が起きやすいので、これを利用しない方法で書きます。

今後のために、以下のファイルを「YOLOX-main」の直下にコピーしておきます。

tools\train.py
tools\demo.py

また、学習モデル「yolox_nano.pth」を以下からダウンロードし、YOLOX-mainの直下に入れておきます。

https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_nano.pth

適当な動画ファイルをつかって、動作確認をします。

python demo.py webcam -n yolox-nano -c .\yolox_nano.pth

なお、この後必要となるので、このフォルダ内に「data」というフォルダを、「datasets」フォルダの下に「COCO」というフォルダを作っておきます。
ちなみに「data」フォルダには、学習させたい画像ファイルを入れておきます。

(1) VoTTで学習データ作成(アノテーション)

まずは、以下からVoTTを入手します。

Releases · microsoft/VoTT

「Assets」の下の「vott-2.2.0-win32.exe」をクリックすると、ダウンロードされます。
ダウンロードが終わったら、これをダブルクリックしてインストールします。

デスクトップにあるvottのアイコンをダブルクリックすると、以下のような画面が出てきます。

20240615-103844

ここでは、新規プロジェクトをクリック。

20240615-104913

すると、こんな感じの画面が出てくるはずです。
表示名は、適当でいいです(ここではtestとしました)。

その下のソース接続、ターゲット接続ですが、ここはそれぞれ先ほど作った「data」と「datasets-COCO」を選びます。

20240611-203735

それぞれの接続の横にある「Add Connection」をクリックすると、上のような表示が出ます。
表示名は適当に入れて、プロバイダーは「ローカルファイルシステム」とすると、その下に「フォルダを選択」というのが出てくるので、フォルダを選択して「接続を保存」をクリックします。

あと、下にある「タブ」には、今回作りたいラベル名を入れておきます。

なお、今回は子供の運動会の画像から「人」と「帽子」を検出するものを作ることにしました。なので、ここは「human」「hat」と入れておきます。

20240615-104830

そこまでできたら、プロジェクトを保存、とします。

20240611-203848

すると、dataフォルダ内にある画像を読み込み、こんな感じの画面が出てきます。
ここで、アノテーションという作業を行います。
具体的には、検出したいものを選択し、ラベル付けするという作業です。これが結構大変。

20240611-203904

まずは、人を囲みます。

20240611-203918

囲んだ後に、右上の出てくるリストから「human」を選択すると、この枠にhumanというラベルが付けられます。
なおこの場合、1つ目が「human」、2つ目が「hat」となっているので、枠を選んだ後に数字の1キーを押すと「human」、2を押すと「hat」とラベル付けされます。
この数字キーでのラベル付けはすごく便利です。

20240611-204514

そんな調子で、じゃんじゃんラベル付けをしていきます。
だいたい1枚の画像から20個程度の人、帽子のラベルを作成、これを25枚ほどやりました。

たった26枚でも、地獄の作業でした。

この作業を終えて保存する前に、画面左の真ん中編にある斜め上矢印のアイコン「エクスポート」をクリックします。

20240611-210004

以下のような画像が出てくるので、プロバイダーを「Pascal VOC」、アセットの状態を「訪問済みアセットのみ」として「エクスポート設定を保存」をクリックします。

その後に、今度は画面上にある、斜め上矢印をクリックします。
すると、アノテーションデータが保存されたというメッセージが出てきます。
これで、学習データの作成は完了です。

※ VoTTは画像だけでなく、動画データからもアノテーションすることが可能です。
 が、Windowsの場合は次の変換以降が上手くいかないので、必ず動画を複数枚の静止画にしてからアノテーションするようにしてください。

(2) Pascal VOC⇒COCOへの変換

YOLOXは学習モデルをCOCOの形式に変換してやる必要があります。
このため、Pascal VOC⇒COCOへ変換するコマンドを使います。

以下のサイトで、「<>Code」から「Download ZIP」を選択。

GitHub - tatsuya-fukuoka/convert_pascalvoc2coco: VOTTで出力したPascal VOC形式のXMLファイルをCOCO形式のJSONファイルへ変換するスクリプト

ダウンロードされたZIPファイルを解凍し、出てきた「convert_pascalvoc2coco-main」というフォルダを「YOLOX-main」の直下に入れます。

「datasets\COCO」の中にあるフォルダ(「test-PascalVOC-export」という名前)を「convert_pascalvoc2coco-main」の中に移動してやります。

そこで、Windows PowerShell上で上のフォルダに移動後、

python convert_vott_voc2coco.py test-PascalVOC-export

と実行。すると[YYYYMMDD_HHMMSS]_COCO_Formatという名前のフォルダができます。
その中にあるフォルダ、ファイル類をごっそり「datasets\COCO」の中に入れます。

(3) 学習実行

いよいよ、学習実行です。
が、ちょっと前準備が必要。

「exp\example\custom」というフォルダにある「nano.py」というファイルを開きます。
その中にある「self.data_dir = "datasets/coco128"」を「self.data_dir = "datasets/COCO"」に書き換えます。

また、self.var_annの下あたりに「self.max_epoch = 300」「self.num_classes = 2

を追記しておきます。(num_classesは自身で作ったラベル数に変えてください)


        self.data_dir = "datasets/COCO"
        self.train_ann = "instances_train2017.json"
        self.val_ann = "instances_val2017.json"

        self.max_epoch = 300
        self.num_classes = 2

こんな感じになっていればOK。

また、ラベル名については、「yolox\data\datasets」にある「coco_classes.py」の中の「COCO_CLASSES = (」以下を書き換えます。今回の場合は、下のようになります。


COCO_CLASSES = (
"human",
"hat",
)

ここは変えなくても動きますが、おかしなラベル名になるので変えておいた方が無難です。

ここでようやく、学習を実行します。

python train.py -f exps/example/custom/nano.py -d 1 -b 16 --fp16 -o --cache

すると、こんな画面が出てきます。

20240615-093303

うちの環境(GTX1650Ti)だと、だいたい30分くらいで300エポックが実行されました。

終わると、「YOLOX_outputs\nano」に~.pthという学習モデルが大量に入っているはずなので、そのなかの「best_ckpt.pth」をYOLOX-mainの直下に移動しておきます。

そこで、適当な動画ファイル(ここでは0002.mp4)を使って推論してみます。

python demo.py video -f exps/example/custom/nano.py -c best_ckpt.pth --path 00002.mp4 --conf 0.3 --tsize 640 --save_result --device gpu

すると「YOLOX_outputs\nano\vis_res」の下にフォルダが作成されて、その中にアウトプットされた動画ファイルが入ってます。

20240615-094221

こんな感じで、ちゃんと?推論されてました。
というか、ちょっとhumanが過検出されてる感はありますが。
(ついでに言うと、humanとhatのラベルがなぜか逆でしたが)

まあ、とりあえず動くことは動きました。
あとはたくさんアノテーションをしてやればよさそうです。

なお、tensorboardを使って学習の状況を確認できます。

tensorboard --logdir .\YOLOX_outputs\nano\tensorboard

とコマンド入力し、下に出てきた「http://localhost:6006」をCTRLキーを押しながらクリックすると、ブラウザが開いてグラフが表示されます。

20240615-094411

これを見ると、100エポックくらいまでは全然学習されてなくて、300の手前で頭打ちになってます。
学習データのアノテーションが、いい加減 or 少なすぎたんですかね?

いずれにせよ、これで独自データによる学習ができました。

実用上はonnx形式に変換してやりたいところ。そうすれば、Raspberry Pi辺りで動かせるんですけどね。まだそちらは上手くいってません。


物体検出とGAN、オートエンコーダー、画像処理入門 PyTorch/TensorFlow2による発展的・実装ディープラーニング

2024年5月25日 (土)

先日の「ローカルLLM+RAG」をGPU上+より大規模モデル(13b)でも動かせるようにしてみた

つい先日に「大規模言語モデル「ELYZA-7b」と自作小説「計算士と空中戦艦」で「RAG」をしてみた: EeePCの軌跡」という記事を書いたばかりですが、あれはCPUが前提でした。

が、やはりもっと大きなモデル使いたいし、GPU対応にもしておきたい、ということで追加でやってみました。

以下、元記事(大規模言語モデル「ELYZA-7b」と自作小説「計算士と空中戦艦」で「RAG」をしてみた: EeePCの軌跡)ができているという前提で、その先にやる手順を書きます。

CUDA 12.1の導入

pytorchとllama-cpp-pythonの両方に対応しているCUDAということで、12.1を使うことにしました。

インストールの方法は、

CUDA Toolkit 12.1 Downloads | NVIDIA Developer

からインストーラーをダウンロードし、それをダブルクリックしてインストールするだけです。

なお、最近のpytorchではcuDNNは不要らしいですが、心配な方は、

cuDNN Archive | NVIDIA Developer

から最新の一つ古いくらいのバージョンをダウンロードしておくといいでしょう。

pytorchのGPU対応

pytorchの公式サイト

Previous PyTorch Versions | PyTorch

にある通り、以下のコマンドを入れます。
(CPU版から上書きするコマンドにしてます)

> pip install --upgrade --force-reinstall torch==2.1.1 torchvision==0.16.1 torchaudio==2.1.1 --index-url https://download.pytorch.org/whl/cu121

ここではとりあえず、前回と同じバージョンのtorchにしておきました。

llama-cpp-pythonのGPU版インストール

以下のコマンドを入れて、入手します。

> pip install llama-cpp-python --extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cu121 --upgrade --force-reinstall --no-cache-dir

なお、llama-cpp-pythonのバージョンは前回の0.2.20から0.2.75と上がりますが、この方がCPU動作時でも早くていい感じでした。

13bモデルダウンロード

前回同様、gitで13bのモデルをダウンロードします。

> git lfs clone https://huggingface.co/mmnga/ELYZA-japanese-Llama-2-13b-fast-instruct-gguf/ --include "ELYZA-japanese-Llama-2-13b-fast-instruct-q8_0.gguf"

この「-fast-」とついたモデルは、精度そこそこで1.8倍速いらしいので、こっちを使うことにします。

プログラムコードの変更

先の記事にあった「elyza_rag.py」の中身で、以下の3か所を書き換えます。

(旧)

model_path = f"models/ELYZA-japanese-Llama-2-7b-instruct-gguf/ELYZA-japanese-Llama-2-7b-instruct-q8_0.gguf"

(新)

model_path = f"models/ELYZA-japanese-Llama-2-13b-fast-instruct-gguf/ELYZA-japanese-Llama-2-13b-fast-instruct-q8_0.gguf"

(旧)

llm = LlamaCPP(
    model_path=model_path,
    temperature=0.1,
    model_kwargs={"n_ctx": 4096, "n_gpu_layers": 32},

(新)

llm = LlamaCPP(
    model_path=model_path,
    temperature=0.1,
    model_kwargs={"n_ctx": 4096, "n_gpu_layers": -1},

(旧)


EMBEDDING_DEVICE = "cpu"

(新)


EMBEDDING_DEVICE = "cuda"

書き換えたものを、別の名前で保存しておきます。
(ここでは「elyza_rag_13b_gpu.py」としておきます)

実行

あとは、普通に実行です。

> python elyza_rag_13b_gpu.py

GPU対応されたとはいえ、起動直後のインデックス化作業はそこそこかかります(数分)。

なお、我が家はメインメモリーが64GBGPUがGeForce GTX1650Ti (GPUメモリー 4GB)という環境であるため、全然GPUメモリーが足りません。
が、メインメモリーの内、最大で半分までをGPUメモリーとして使える(共有GPUメモリ―として認識)ため、どうにか動きました。

20240525-133250

実行中のメインメモリーはこんな感じ。

20240525-133249

GPUの方も共有を含め、かなり目一杯使ってます。

そんな環境下ですが、前回と同じ質問を投げかけてその回答時間を比較します。
よく見たら、推論時間が回答の直上に書かれていたので、それを貼り付けます。
(CPUでも13bモデルを走らせての比較です。)

(CPU版)

20240525-132219

(GPU版)

20240525-130244

ざっと4分弱 → 2分強程度まで縮まりました。
残念ながらGPUがしょぼいので、さほど高速化の実感はありませんが、それでも速いことは速い。

さて、せっかくモデルのサイズを大きいものにしたので、それを実感できる文例を期待してます。
ということで、前回はおかしな回答か、あるいは回答不可と出た質問文を投げかけてみます。

## Question: ヴェテヒネンでのビスケットの食べ方は?

## Answer:
私は石のように硬いビスケットを豆スープに突っ込むと、少しだけ水分を含んで柔らかくなったそれにかじりつく。歯が折れそうな ほどの硬いビスケットを二欠け程口に含んだところで、豆スープを一気に流し込む。さらに干し肉にもかかじりつくと、今度はその独特の臭みをごまかすため、紅茶で口の中を洗浄する。

うん、まあ、文章を抜き出してきただけのような気がしますが。間違ってはいない。

## Question: ヴェテヒネンの乗員は何人いますか?

## Answer:
26名です。

これは簡単だったかな?でも7bモデルでは「回答できません」的なことを言われました。

## Question: 中央計算局とは?

## Answer:
中央計算局は真四角なコンクリート製で、窓がほとんどない殺風景な建屋だ。近所に並び立つ貴族街の優美で荘厳な屋敷や、窓の多 い軍司令本部の建物と比べると、味気ない場所ににしか見えない。

建物の特徴ではなく、何をするところかを聞きたかったんですが、質問が悪いですかね。

ということで、2分ほどで前回よりも良質な回答ができるようになりました。
が、読ませる文書ファイルがあまり良くないですね。できれば、もうちょっとビジネス文書的なもので試してみたいところです。


面倒なことはChatGPTにやらせよう (KS情報科学専門書)

より以前の記事一覧

無料ブログはココログ

スポンサード リンク

ブログ村