ラベル 機械学習 の投稿を表示しています。 すべての投稿を表示
ラベル 機械学習 の投稿を表示しています。 すべての投稿を表示

2026年5月17日日曜日

RAGとLoRAの使い分け:LLMの知識拡張と個別最適化のアーキテクチャ

はじめに:LLMの知識拡張における二つの選択肢

企業が生成AIを導入する際、直面する最大の壁は「モデルが自社の固有知識を持っていない」という点です。ChatGPTのような汎用LLMは高度な推論能力を持ちますが、機密性の高い社内文書や、直近の市場動向については学習していません。

この課題を解決するための主要なアプローチとして、外部知識を検索する「RAG(Retrieval-Augmented Generation)」と、モデルの挙動やトーンを微調整する「LoRA/QLoRA」が存在します。これらを単なる手段としてではなく、ビジネスの「知識管理戦略」という観点から比較・検討します。

RAG:外部データベースを「脳の外部メモリ」にする

RAGは、LLM本体を改変せず、社内文書などをベクトルデータベースに格納し、プロンプトのコンテキストとして渡す手法です。いわば「オープンブック試験」をモデルに行わせるような設計です。

なぜRAGを選ぶのか

  • 情報の鮮度管理: データベースを更新するだけで知識を最新化できるため、頻繁に変わる社内ルールや市場データの扱いに適しています。
  • ハルシネーションの低減: 根拠となるドキュメントを提示できるため、モデルが事実に基づいた回答を行いやすくなります。
  • コスト効率: モデル本体を再学習するコストがかからないため、スタートアップや中規模プロジェクトでの導入に適しています。

LangChainを用いた実装の勘所

LangChainは、このRAGプロセスをパイプラインとして構造化するために最適です。例えば、以下の流れで実装します。

from langchain.vectorstores import Chroma
from langchain.chains import RetrievalQA

# ドキュメントをベクトル化してロード
vectorstore = Chroma(persist_directory="./db", embedding_function=embeddings)

# 検索と生成のパイプライン構築
qa_chain = RetrievalQA.from_chain_type(llm=llm, retriever=vectorstore.as_retriever())

# 実行
result = qa_chain.run("社内の有給休暇申請フローを教えて")

重要なのは「検索精度」です。ドキュメントの分割粒度や、検索エンジンに渡すクエリの最適化がシステムの質を決定します。

LoRA:モデルの「話し方」と「振る舞い」を個別最適化

一方で、「特定の出力形式を守らせたい」「専門的な文脈に沿った回答をさせたい」といったニーズには、モデル自体を微調整する「LoRA(Low-Rank Adaptation)」が有効です。

LoRAの技術的背景

LoRAは、全パラメータを更新する「Full Fine-tuning」とは異なり、モデルの重み行列に低ランク行列を挿入して加算する手法です。これにより、数%のパラメータを学習するだけで、元のモデルの知識を維持しつつ、特定のタスクに適応させることが可能です。特にメモリ消費を抑える「QLoRA」の登場により、民生用GPUでの学習も現実的な選択肢となりました。

使い分けの基準

  • タスクの複雑性: 言語生成のスタイルや専門用語の用法といった「振る舞い」を変えたい場合はLoRAが適しています。
  • 知識の依存度: 新しい事実を覚えさせたい場合はRAGが勝ります。LoRAは知識の「暗記」には不向きであり、あくまで「推論能力のチューニング」と捉えるべきです。

どちらを選ぶべきか:設計の意思決定

実務において、これらは二者択一ではありません。多くのエンタープライズ環境では「RAGで専門知識を供給し、LoRAで回答のトーンと精度を担保する」というハイブリッドな構成が理想的です。

設計の際は、まずはRAGを実装し「知識の欠落」を埋めることから始めてください。その上で、回答の構造が安定しない、特定の社内フォーマットに従わないといった「出力の品質」に課題を感じた段階で、LoRAによる微調整を検討するロードマップが、最も失敗の少ないアプローチです。

AIを単なるツールとして利用するのではなく、組織内の知識エコシステムとしてどのように組み込むか。そのアーキテクチャの選択こそが、技術導入の成否を分ける鍵となります。

2020年4月23日木曜日

機械学習と深層学習

「機械学習と深層学習って何が違うの」という質問を受けることが良くあるが、その説明としてこの図がわかりやすいのかなと思う。

「機械学習」というのは、何らかのパターンを自動で覚えて、次に何らかのパターンが発生したときに、過去に覚えたパターンと近いかどうかを判別したり、次にどういうパターンになるかを予測するようなプログラムのこと。
パターンというのは、例えば画像だったり、文字列だったり、株価の毎日の変動だったり。例えば、犬の画像をたくさん覚えた機械学習に動物の写真を入力すると犬かどうか判別したりできるし、株価のデータを入力すると次の日に上がるか下がるかを過去のパターンから予測してくれるようになる。 自動で覚えてとは書いたが人がそれらのデータを集めて機械学習のプログラムに覚えさせてもいいと思う。

一方で「深層学習」とは「ディープラーニング」や「ディープニューラルネットワーク(DNN)」とも呼ばれるが、機械学習をするための一つの手法のこと。これのベースになっている「ニューラルネット」という技術は神経細胞に似た網目構造を使って計算する方式で何十年も前から知られていて、網目構造を増やす(層を深くする)と性能が上がることはわかっていた。しかし昔はコンピューターが非力だったので少し増やすと計算が終わらず使い物にならなかったのが、最近はまともに動くようになってきて性能も高く実用的になったので一気に知名度が上がってきたというものである。

ただ、深層学習は一気に知名度が上がったので、世の中的には機械学習=深層学習と見てしまわれることが多い。そんな感じで冒頭の質問をされた時には、ちょっと古いが、ヘッドホンステレオ=ウォークマンと同じイメージと説明している。

深層学習の中にも層の作り方やデータの処理の仕方でいろいろな方法があって、画像判定が得意とか、予測が得意とか、用途に応じて使い分けられている。 例えば、最後に紹介するDEEPという深層学習では文章を解析して分類することができるものとなっていて、ここの研究論文にあるような飲食店のレビュー文章を分析することをしている。

2014年9月22日月曜日

Mahoutでレコメンドを動かすまで(その2)

嗜好をもとにしたレコメンドをする
Mahoutにはrecommenditembasedというレコメンドを計算する機能を持っており、Amazonのように他の人の嗜好をもとにしたレコメンドを計算することができます。 今回はそれに挑戦してみたいと思います。

データを準備する
まずレコメンドの元となる各ユーザーの嗜好を表すデータを準備します。これはエクセルかテキストエディタで以下のような3列の数値データを用意します。書式は以下のようになっておりすべて数値で表します。今回はrecommend.txtという名前でファイルを保存しました。

  • 1列目 - おすすめしている人のID
  • 2列目 - おすすめしているアイテムのID
  • 3列目 - 嗜好の度合い(いくつでもいい?)

例えば次のような場合、1行目はユーザーIDが1の人が、アイテム番号100を気に入っており、その度合いが5を表しています。

1,100,5
1,200,3
1,300,3
2,100,5
2,200,5
2,400,3
2,900,4
3,200,4
3,300,5
3,700,4
4,200,5
4,400,4
4,600,5
4,900,5
5,100,5
5,200,3
5,400,4
5,500,6
5,700,5
6,100,3
6,200,4
6,400,2
6,700,3
7,100,4
7,700,5
7,800,5
7,900,5

列はどれも数値にする必要があります。現状持っているデータのユーザーIDなどが文字列の場合は変換テーブルを作って数値を割り振るような対応になるんでしょうね。

レコメンドを計算する

データが準備できたら以下のコマンドを使って早速計算をしてみます。

bin/mahout recommenditembased -i recommend.txt -o recommend_out -s SIMILARITY_PEARSON_CORRELATION

ここの環境だと計算に10秒近くかかりました。

結果は引数で指定したrecommend_outフォルダのファイルpart-r-00000に記録されます。 今回のサンプルの結果だと以下のようになります。各行がそれぞれのユーザーへのおすすめを示しており、1行目はユーザーIDが2の人へのおすすめはアイテム番号700で、スコアが3.9172406というのを示しているようです。

vmplanet@ubuntu:~/mahout-distribution-0.9$ cat recommend_out/part-r-00000
2     [700:3.9172406]
4     [700:4.19286]
5     [900:4.375]
6     [900:2.375]
7     [400:4.6099067]

数字だけ見ていると合っているのかはピンときませんが、一応レコメンドが計算できたようです。

元データが少ないと結果が0バイトになる
元データが少なすぎると出力が空になってしまうようです。最初はオプションなどの使い方の問題かと思いましたが元データを増やしたらレコメンドが得られるようになりました。

vmplanet@ubuntu:~/mahout-distribution-0.9$ ls -l recommend_out/
合計 4
-rwxrwxrwx 1 vmplanet vmplanet  0 2014-09-18 20:33 part-r-00000
-rwxrwxrwx 1 vmplanet vmplanet  0 2014-09-18 20:33 _SUCCE

正確にはわかりませんが、元データが20行くらいになると結果が出てくるようです。

元データの最後に改行があるとエラー
元データのCSVファイルの最後に改行があるとエラーになるようです。 その場合は以下のエラーが発生するので、そのときは元データファイルの見直しをするとよいと思います。

14/09/18 20:43:26 WARN mapred.LocalJobRunner: job_local1173485433_0001
java.lang.Exception: java.lang.ArrayIndexOutOfBoundsException: 1
at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:354)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 1
at org.apache.mahout.cf.taste.hadoop.item.ItemIDIndexMapper.map(ItemIDIndexMapper.java:50)

出力フォルダとtempフォルダがあるとエラー

データを変更して再度計算しようと思いコマンドを再実行したところ以下のエラーとなりました。

14/09/18 20:35:35 ERROR security.UserGroupInformation: PriviledgedActionException as:vmplanet cause:org.apache.hadoop.mapred.FileAlreadyExistsException: Output directory temp/preparePreferenceMatrix/itemIDIndex already exists

出力先で指定したフォルダと、計算途中でできたtempフォルダがあるとエラーになるので、実行前には以下のコマンドできれいにしてから実行するといいでしょう。

rm -rf temp/ recommend_out/

Mahoutでレコメンドを動かすまで(その1)

はじめに

機械学習というと何やらすごく神秘的なものを感じます。 その機械学習のためのツールにMahoutというものがあると聞き早速試してみることに。

まずはWindowsで動かしAmazonのレコメンドみたいなものをやってみようといろいろ試しました、が、いろいろなエラーに遭遇したため一旦挫折、まずはLinuxを使うことにしました。 Windowsの方はまた動かせるようになったら報告します。

Linux版の方でも動かすためにはいろいろ躓くポイントがありました。以下、とりあえず動かすまでにやったことを記します。環境は以下を使用しました。まずはお試しということでHadoopは無しでやっています。

  • Ubuntu 10.0.4
  • Mahout 0.9
JAVA_HOMEが必要

Mahoutをダウンロード、展開していきなりコマンドをたたくと、以下のように怒られます。環境変数JAVA_HOMEにJavaのインストール先を設定する必要があるようです。

vmplanet@ubuntu:~/mahout-distribution-0.9$ bin/mahout
Error: JAVA_HOME is not set.

MAHOUT_JAVA_HOMEがあるときはJAVA_HOMEのかわりにこちらが使われるとのことなので、この変数にJavaのインストール先を設定します。

export MAHOUT_JAVA_HOME=/usr/lib/jvm/java-6-openjdk

ちなみに環境変数の一覧はbin/mahoutの中を除くと説明が書いてあります。

ヒープが足りない

使っていたLinux環境のメモリが少なかったのが原因ですがMAHOUT_JAVA_HOMEを設定して動かすと今度は以下のエラーになりました。

vmplanet@ubuntu:~/mahout-distribution-0.9$ bin/mahout 
hadoop binary is not in PATH,HADOOP_HOME/bin,HADOOP_PREFIX/bin, running locally
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

ヒープを確保できなかったというエラー。確保するヒープサイズはMAHOUT_HEAPSIZEに設定するようです。単位はMBです。指定しない場合のデフォルトは1024らしいので、これだけ確保しようとして失敗していたのが原因のようです。

とりあえず以下のように少し少なめに設定しました。

export MAHOUT_HEAPSIZE=512

ここまで設定してやっと動くようになりました。 引数を何もつけないで実行すると使える分析アルゴリズムの一覧が表示されます。

vmplanet@ubuntu:~/mahout-distribution-0.9$ bin/mahout
hadoop binary is not in PATH,HADOOP_HOME/bin,HADOOP_PREFIX/bin, running locally
An example program must be given as the first argument.
Valid program names are:
  arff.vector: : Generate Vectors from an ARFF file or directory
  baumwelch: : Baum-Welch algorithm for unsupervised HMM training
  canopy: : Canopy clustering
  cat: : Print a file or resource as the logistic regression models would see it
  cleansvd: : Cleanup and verification of SVD output
  clusterdump: : Dump cluster output to text
  clusterpp: : Groups Clustering Output In Clusters
  cmdump: : Dump confusion matrix in HTML or text formats
  concatmatrices: : Concatenates 2 matrices of same cardinality into a single matrix
  cvb: : LDA via Collapsed Variation Bayes (0th deriv. approx)
  cvb0_local: : LDA via Collapsed Variation Bayes, in memory locally.
  evaluateFactorization: : compute RMSE and MAE of a rating matrix factorization against probes
  fkmeans: : Fuzzy K-means clustering
  hmmpredict: : Generate random sequence of observations by given HMM
  itemsimilarity: : Compute the item-item-similarities for item-based collaborative filtering
  kmeans: : K-means clustering
  lucene.vector: : Generate Vectors from a Lucene index
  lucene2seq: : Generate Text SequenceFiles from a Lucene index
  matrixdump: : Dump matrix in CSV format
  matrixmult: : Take the product of two matrices
  parallelALS: : ALS-WR factorization of a rating matrix
  qualcluster: : Runs clustering experiments and summarizes results in a CSV
  recommendfactorized: : Compute recommendations using the factorization of a rating matrix
  recommenditembased: : Compute recommendations using item-based collaborative filtering
  regexconverter: : Convert text files on a per line basis based on regular expressions
  resplit: : Splits a set of SequenceFiles into a number of equal splits
  rowid: : Map SequenceFile to {SequenceFile, SequenceFile}
  rowsimilarity: : Compute the pairwise similarities of the rows of a matrix
  runAdaptiveLogistic: : Score new production data using a probably trained and validated AdaptivelogisticRegression model
  runlogistic: : Run a logistic regression model against CSV data
  seq2encoded: : Encoded Sparse Vector generation from Text sequence files
  seq2sparse: : Sparse Vector generation from Text sequence files
  seqdirectory: : Generate sequence files (of Text) from a directory
  seqdumper: : Generic Sequence File dumper
  seqmailarchives: : Creates SequenceFile from a directory containing gzipped mail archives
  seqwiki: : Wikipedia xml dump to sequence file
  spectralkmeans: : Spectral k-means clustering
  split: : Split Input data into test and train sets
  splitDataset: : split a rating dataset into training and probe parts
  ssvd: : Stochastic SVD
  streamingkmeans: : Streaming k-means clustering
  svd: : Lanczos Singular Value Decomposition
  testnb: : Test the Vector-based Bayes classifier
  trainAdaptiveLogistic: : Train an AdaptivelogisticRegression model
  trainlogistic: : Train a logistic regression using stochastic gradient descent
  trainnb: : Train the Vector-based Bayes classifier
  transpose: : Take the transpose of a matrix
  validateAdaptiveLogistic: : Validate an AdaptivelogisticRegression model against hold-out data set
  vecdist: : Compute the distances between a set of Vectors (or Cluster or Canopy, they must fit in memory) and a list of Vectors
  vectordump: : Dump vectors from a sequence file to text
  viterbi: : Viterbi decoding of hidden states from given output states sequence

お勧め商品などのレコメンドを計算するにはrecommenditembasedというアルゴリズムを使います。早速これを使ったレコメンドをしてみたいと思いますが長くなったので続きは次回。

【 →その2に続く... 】