[AI] ChatRWKVアプリ製作 その7 Ubuntuへの移植完了 PyQt5

[RTX 4070Ti, Ubuntu 22.04.1, CUDA 11.8, PyTorch 2.0.0]

AI研究用PCのOSをWindows11からUbuntuに変更しました。

NVIDIA Driver、CUDAとそれらに適合したPyTorchのインストールに手間取りましたが、MacOSと同じUNIX系OSということもありその後はスムーズでした。

気になったこととして、Windowsでは関連ライブラリのバージョンを変えてチャットを実行する度に回答能力の大きなブレが生じており、MacOSやUbuntuではブレは殆どありませんでした。裏付けデータ不足で断定は出来ませんが、少なくとも私はそう感じました。ただUTF-8とShift-JISの違いでそのようなことが起こるとは思えないです。

なおLinuxはPyQt6には対応していないため、PyQt5にダウングレードしました。

[AI] ChatRWKVアプリ製作 その6 Windows11への移植断念 PyQt6

[RTX 4070Ti, Windows11]

ChatRWKVアプリをMacOSからWindows11へ移植しようとしたものの、ターミナル系ツールに質問となる文字列を貼り付けることが出来ませんでした。

コマンドプロンプト、PowerShell、Windowsターミナルどれもダメでした。前2者は貼り付けようとすると落ちてしまいますし、後者は落ちはしませんが全く書き込めません。設定を変えても改善せず。ウィンドウサイズさえ反映されないのはもはや意味不明。ツールのクラッシュだとしたら堅牢性ゼロと評価せざるを得ないです。

まさかWindowsでのAI研究2日目で馬脚を現すとは思いませんでした。GUIはMacOS版より良かったのですが残念です。

エクスプローラでファイルパスをコピーするとバックスラッシュ表記になり、そのままUTF-8のスクリプトに貼り付けると意図せずエスケープシーケンス混入スクリプトに化けるなどトラブル多発OSでもありますから見切られても仕方ないでしょう。

なおこの問題は該当箇所だけスラッシュに書き換えれば解決します。バックスラッシュとスラッシュが混ざっていてもパスとして成立する何とも奇妙なOSです。

明日以降、Linuxと入れ替えます。私の中でMacOS、Windows、Linuxだった序列がついにMacOS、Linux、(Windows)になりそうです。UTF−8文化圏で遊ぶのが私には最良なのでしょう。

ChatRWKVアプリWin版(開発中止予定)

[AI] ChatRWKV 動作確認 RTX 4070Tiを投入

RTX 4070Tiを搭載したWindows機を組みました。RAMは64GBに増設しました。

GPUなしでは厳しかったパラメータ数14Bの学習モデルを使うことが出来ました。初歩的なコーディングもOKです。

strategy設定をGPU→CPUにして、GPUのリソースを消費後、CPUに移行するようにすると上手くいきました。文字出力の速度は日本語2文字/秒といったところです。なおGPU単体ではチャット開始までにVRAM12GBを消費して中断してしまいます。

7Bはコーディングが全く出来ませんが14Bはなかなかいい感じです。どこまで書けるかはこれから検証します。

args.strategy = 'cuda fp16i8 -> cpu fp32 *10'
# args.strategy = 'cuda fp16i8' リソース不足エラーになる

[AI] LlamaIndexアプリ製作 その10 ディレクトリへの対応

[M1 Mac, Ventura 13.3.1, Python 3.10.4]

これまでCSVとPDFの単ファイルに対応していましたが、ディレクトリ内の複数ファイルにも対応できるようにしました。TXTファイルも読み込めます。

def makeIDX(self):
    # インデックスの作成および保存
    llm_predictor = LLMPredictor(llm=OpenAI(temperature=0, model_name="gpt-3.5-turbo"))
    service_context = ServiceContext.from_defaults(llm_predictor=llm_predictor)
    
    data_path = self.input.text()
    data_path2 = data_path.replace("'", "") # 拡張子判定用
    data_path3 = Path(data_path2) # loader用

    if data_path2.endswith('/'):
        documents = SimpleDirectoryReader(data_path3).load_data()
    elif data_path2.endswith('.csv'):
        SimpleCSVReader = download_loader("SimpleCSVReader")
        documents = SimpleCSVReader().load_data(file=data_path3)
    elif data_path2.endswith('.pdf'):
        PDFReader = download_loader("PDFReader")
        documents = PDFReader().load_data(file=data_path3)
    else:
        print('入力がディレクトリ,csv,pdfではありません')
        self.output.setText("入力がディレクトリ,csv,pdfではありません")
        self.box.setStyleSheet('background-color: #ff00ff')
        return

    index = GPTSimpleVectorIndex.from_documents(documents, service_context=service_context)
    
    now = datetime.datetime.now()
    formatted_time = now.strftime('%y%m%d_%H%M%S')

    index_file = "/Volumes/DATA_m1/AI/LlamaIndex/index/" + formatted_time + "_index.json"
    index.save_to_disk(index_file)
    
    self.input2.setText(index_file)
    self.idxBtn2.click()

[AI] LlamaIndexとLangChain(Chroma)の比較 その2 要約力

[M1 Mac, Ventura 13.3.1, Python 3.10.4]

今度は要約力を比較しました。とある英語論文のPDF1ページ目を読み込ませて、要約してもらいました。

こちらでもLlamaIndexに軍配があがりました。ここでLangChain(Chroma)が優れているのであれば、Embeddings Toolアプリとして両者を統合する目論見でしたが、現時点では正確性・要約力で明らかにLangChain(Chroma)が劣っているため見送りです。

.py /usr/local/bin/python /Volumes/DATA_m1/AI/LangChain/Python/ChatGPT_LangChain 
Using embedded DuckDB with persistence: data will be stored in: .
この論文では、大規模言語モデルマシン(LLMM)と高水準プログラミング言語のクラスとの間に接続を
確立する新しいアプローチを提案しています。これにより、Turingマシンオブジェクトと言語オブジェクトの間の
シームレスな相互作用が可能になり、普遍的にアクセス可能なオブジェクト指向の記述が実現されます。
LLMMを利用して、現実世界のオブジェクトとそれらのシミュレーションを言語シミュレーション可能な
世界に自動的に変換する方法を示し、デジタルツインコンセプトを推進します。このプロセスは高水準
プログラミング言語に拡張することができ、これらのシミュレーションの実装をよりアクセスしやすく
実用的にすることができます。

[AI] LlamaIndexとLangChain(Chroma)の比較 その1 正確性

[M1 Mac, Ventura 13.3.1, Python 3.10.4]

表題の2方法について、PDFを読み込ませた上で質問に対して正確に答えられるかどうか評価しました。

結果はLlamaIndexの圧勝でした。LangChain(Chroma)ではPDFにあるはずのデータを存在しないと返してきました。これでは話になりません。

LangChain(Chroma)では有力なベクトルDBであるChromaを使っていますが、苦手な処理だったのか正確性ではLlamaIndexとは比較になりませんでした。要約力であればまた結果が違ってくるのかもしれません。

import os
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.text_splitter import CharacterTextSplitter
from langchain.chat_models import ChatOpenAI
from langchain.chains import ConversationalRetrievalChain
from langchain.document_loaders import PyPDFLoader

loader = PyPDFLoader("試合日程表.pdf")
pages = loader.load_and_split()

# print(pages[1].page_content)

apiKey = os.getenv("CHATGPT_API_KEY")
os.environ["OPENAI_API_KEY"] = apiKey

llm = ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo")

embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(pages, embedding=embeddings, persist_directory=".")
vectorstore.persist()

pdf_qa = ConversationalRetrievalChain.from_llm(llm, vectorstore.as_retriever(), return_source_documents=True)

query = "XXXの試合はいつですか"
chat_history = []

result = pdf_qa({"question": query, "chat_history": chat_history})

print(result['answer'])

参考サイト

[AI] ChatRWKVアプリ製作 その5 LangChainでRWKVを使う PyQt6

[M1 Mac, Ventura 13.3.1, Python 3.10.4]

LangChainでRWKV学習モデルを試してみました。

LangChainはこれまで3/31リリースの0.0.127を使っていました。このバージョンではRWKVは使えませんでしたが、現時点最新の0.0.146では使用可能になっています。毎日、新バージョンをリリースしているのでこまめにチェックが必要ですね。

パラメータ数1B5で受け答えがややまともになりましたが、M1 Macでは動作が遅すぎます。日本の首都を答えるのに3分掛かりました。

class chat_base():
    def __init__(self):
        self.model_tokens = []
        self.model_state = None
        self.all_state = {}
        self.user = None
        self.bot = None
        self.interface = None
        self.init_prompt = None
        self.pipeline = None
        self.bool_value = False
        
    def load_model(self, lang, strat, model, bool):
        self.lang = lang
        self.strat = strat
        self.model = model
        self.bool = bool
        
        if self.bool == False:
            from langchain.llms import RWKV
            
            llm = RWKV(
                model = '/Volumes/DATA_m1/AI/ChatRWKV_work/' + self.model, 
                strategy = self.strat, 
                tokens_path = "/Volumes/DATA_m1/AI/ChatRWKV_work/ChatRWKV/v2/20B_tokenizer.json"
            )
            
            while True:
                print("質問を入力して下さい")
                self.question = input()
                print(llm(self.generate_prompt(self.question)))

参考サイト

[AI] ChatRWKVアプリ製作 その3 chat.pyのクラス化 仮完了 

[M1 Mac, Ventura 13.3.1, Python 3.10.4]

ChatRWKVアプリでmodel, language, strategyを選択できるようにしました。スクリプトをいちいち書き換える手間が省けるので、検証用ツールとして有用です。

chat.pyからメイン部分と各関数を抽出してクラスにまとめています。C++とは別種のややこしさがあってかなり手間取りました。

C/C++ではexternやヘッダファイルを駆使してファイル間で変数を自在に使っていますが、Pythonでは循環importになってしまい、いらいらが募ります。まあC/C++が自由すぎるのでしょう。

チャットボットを使ってみたところ、M1 Mac RAM 8GBで速度的に問題なく動作する436Mのモデルでは会話にならないです。

これで検証用ツール製作という目的はほぼ達成しましたが、ここまできたらGUI上で会話できるようにしたいです。

import os, copy, types, gc, sys
import numpy as np
from prompt_toolkit import prompt
import torch

END_OF_TEXT = 0
END_OF_LINE = 187
CHUNK_LEN = 256 # split input into chunks to save VRAM (shorter -> slower)

CHAT_LEN_SHORT = 40
CHAT_LEN_LONG = 150
FREE_GEN_LEN = 256

GEN_TEMP = 1.1 # It could be a good idea to increase temp when top_p is low
GEN_TOP_P = 0.7 # Reduce top_p (to 0.5, 0.2, 0.1 etc.) for better Q&A accuracy (and less diversity)
GEN_alpha_presence = 0.2 # Presence Penalty
GEN_alpha_frequency = 0.2 # Frequency Penalty
AVOID_REPEAT = ',:?!'

class chat_base():
    def __init__(self):
        self.model_tokens = []
        self.model_state = None
        self.all_state = {}
        self.user = None
        self.bot = None
        self.interface = None
        self.init_prompt = None
        self.pipeline = None
        
    def load_model(self, lang, strat, model):
        self.lang = lang
        self.strat = strat
        self.model = model
        
        CHAT_LANG = self.lang # English // Chinese // more to come
        PROMPT_FILE = f'/Volumes/DATA_m1/AI/ChatRWKV_work/ChatRWKV/v2/prompt/default/{CHAT_LANG}-2.py'
        self.load_prompt = self.load_prompt(PROMPT_FILE)
        
        sys.path.append('/Volumes/DATA_m1/AI/ChatRWKV_work/ChatRWKV/rwkv_pip_package/src')
        
        try:
            os.environ["CUDA_VISIBLE_DEVICES"] = sys.argv[1]
        except:
            pass
        np.set_printoptions(precision=4, suppress=True, linewidth=200)
        args = types.SimpleNamespace()

        print('\n\nChatRWKV v2 https://github.com/BlinkDL/ChatRWKV')
        
        torch.backends.cudnn.benchmark = True
        torch.backends.cudnn.allow_tf32 = True
        torch.backends.cuda.matmul.allow_tf32 = True

<以下略>

[AI] ChatRWKVアプリ製作 その2 LangChainの追加

[M1 Mac, Ventura 13.3.1, Python 3.10.4]

RWKVのモデルをLangChainでも使えるようにGUIを書き換えました。

import os, sys
from PyQt6.QtWidgets import QLabel,QWidget,QApplication,QTextEdit,QLineEdit,QPushButton,QComboBox, QLabel, QRadioButton, QButtonGroup
from PyQt6.QtCore import Qt
from langchain import OpenAI
import chat_base

class ChatRWKV(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("RWKV")
        self.setGeometry(100,100,480,640)
        self.setStyleSheet('background-color: #165E83') # 藍色 あいいろ
        self.setAcceptDrops(True)
        
        # 信号
        self.box = QLabel(self)
        self.box.setGeometry(420,15,50,50)
        self.box.setStyleSheet('background-color: #3E62AD') # 杜若色 かきつばたいろ
        
        tool = QLabel('TOOL',self)
        tool.setGeometry(10,15,40,20)
        tool.setStyleSheet('color: #FFFFFF; font-size: 14pt;')
        tool.setAlignment(Qt.AlignmentFlag.AlignLeft)
        
        self.rbtn1 = QRadioButton('ChatRWKV', self)
        self.rbtn1.setGeometry(60,10,100,25)
        self.rbtn1.setChecked(True) 

        self.rbtn2 = QRadioButton('LangChain', self)
        self.rbtn2.setGeometry(170,10,100,25)
        
        # ラジオボタングループの作成
        self.group = QButtonGroup(self)
        self.group.addButton(self.rbtn1)
        self.group.addButton(self.rbtn2)

<以下略>