本格的なエロチャットAIを作りたい その8(LLMも実装して、LightChatAssistantのエロチャットを実現する)
まずは第一弾としてのパーツが揃ったので、合体させて実装する。
実際のコード
Google colab:LLM_API.ippy
# LLM setting
# 環境変数の設定
!set LLAMA_CUBLAS=1
!set CMAKE_ARGS=-DLLAMA_CUBLAS=on
!set FORCE_CMAKE=1
# llama-cpp-pythonとPyTorchのインストール
!python -m pip install llama-cpp-python==0.2.77 --prefer-binary --extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cu122
!pip install torch==2.3.0 torchvision==0.18.0 torchaudio==2.3.0 --index-url https://download.pytorch.org/whl/cu121
!wget https://huggingface.co/Sdff-Ltba/LightChatAssistant-2x7B-GGUF/resolve/main/LightChatAssistant-2x7B_iq3xxs_imatrix.gguf
from llama_cpp import Llama
llm = Llama(
model_path="LightChatAssistant-2x7B_iq3xxs_imatrix.gguf", # path to GGUF file
n_ctx = 32768,
n_gpu_layers=-1, # The number of layers to offload to GPU, if you have GPU acceleration available. Set to 0 if no GPU acceleration is available on your system.
# n_gpu_layers=0, # The number of layers to offload to GPU, if you have GPU acceleration available. Set to 0 if no GPU acceleration is available on your system.
)
# Communication
import requests
import json
import time
response_data = '*****EMPTY*****'
poling_data = '*****REQUEST*****'
url = "http://ローカルPCのIPアドレス:8080/" # IPアドレスは隠させてもらいました
headers = {'Content-type': 'application/json'}
while True:
if response_data == '*****EMPTY*****':
send_data = poling_data
else:
output = llm(
prompt=response_data,
max_tokens=256,
#stop ="\n",
echo=False,
)
assistant_message = output['choices'][0]['text']
print('AI_OUTPUT:\n' + assistant_message)
send_data = assistant_message
data = {"message": "Send data", "data": send_data}
response = requests.post(url+'/api', data=json.dumps(data), headers=headers)
response_data = response.json().get("data")
print(response_data)
if '*****SHUTDOWN*****' in response_data:
break
elif '*****EMPTY*****' in response_data:
time.sleep(10)
ローカルPC
# Google Colab start module
import pyautogui
import time
import os
# Google Colabを起動させる関数を定義
# 開いている「LLM_API.ipynb - Colab」タブをフォーカスし、Ctrl+F9(すべてのセルを実行)をスローする
def focus_browser_and_send_startup_shortcut():
# ブラウザのウィンドウタイトルの一部(例:'Chrome'や'Firefox')
browser_title = 'LLM_API.ipynb - Colab' # 使用しているブラウザに応じて変更してください
try:
# ブラウザウィンドウを探してアクティブにする
window = pyautogui.getWindowsWithTitle(browser_title)[0]
window.activate()
# ウィンドウがアクティブになるまで少し待つ
time.sleep(1)
# Ctrl+F9のショートカットを送信
pyautogui.hotkey('ctrl', 'f9')
print(f"ショートカット Ctrl+F9 を {browser_title} に送信しました。")
except IndexError:
print(f"エラー: '{browser_title}' というタイトルのウィンドウが見つかりません。")
except Exception as e:
print(f"エラーが発生しました: {e}")
# Google Colabを終了させる関数を定義
# 開いている「LLM_API.ipynb - Colab」タブをフォーカスし、Ctrl+F1(「ランタイムを接続解除して削除」に割り当てたショートカット)をスローし、
# Pop upが出るのでEnterキーを送って終了させる
def focus_browser_and_send_shutdown_shortcut():
# ブラウザのウィンドウタイトルの一部(例:'Chrome'や'Firefox')
browser_title = 'LLM_API.ipynb - Colab' # 使用しているブラウザに応じて変更してください
try:
# ブラウザウィンドウを探してアクティブにする
window = pyautogui.getWindowsWithTitle(browser_title)[0]
window.activate()
# ウィンドウがアクティブになるまで少し待つ
time.sleep(1)
# Ctrl+F1のショートカットを送信
pyautogui.hotkey('ctrl', 'f1')
print(f"ショートカット Ctrl+F1 を {browser_title} に送信しました。")
time.sleep(5)
# ENTERを送信
pyautogui.press('enter')
print(f"Enter を {browser_title} に送信しました。")
except IndexError:
print(f"エラー: '{browser_title}' というタイトルのウィンドウが見つかりません。")
except Exception as e:
print(f"エラーが発生しました: {e}")
# Coogle colabを起動する関数を実行
focus_browser_and_send_startup_shortcut()
# Flask API Receiver start
from flask import Flask, request, jsonify
import threading
system_prompt = '''
SYSTEM:
あなたの名前は里穂
養女である里穂は、恥ずかしがりで処女。
本当は性に強い興味があるが口には出さない。
義父である英樹の入浴姿を覗き見して、その陰部の大きさに驚き、それをおかずに毎晩自慰をしている。
英樹には父親以上の愛情を持っているが、自分からは決して口にしない。
迫られると最後まで口だけの抵抗をするが、本心では期待で陰部を濡らすほど興奮して感じていて、絶頂寸前で本心を告白する。
返事は必ず最初に「里穂: 」を付けてください。
'''
chat_log = '''里穂: おはようございます、お義父さん。今日は私の18歳の誕生なの。お祝いしてくれる?
英樹: あ、おはよう、里穂。もちろんお祝いするよ。今日は特別なプレゼントがあるんだ
里穂: え?ほんと?!お義父さん…すっごく嬉しい!
'''
user_input = ''
user_input_stop_flag = False
shutdown_flag = False
print(chat_log)
app = Flask(__name__)
@app.route("/api", methods=["POST"])
def process_request():
data = request.json
receive_data = data.get("data")
chat_prompt = receive_data_analyze(receive_data)
result = {"message": "Received data", "data": chat_prompt}
return jsonify(result)
# Flaskのログ出力を無効にする
import logging
log = logging.getLogger('werkzeug')
log.setLevel(logging.ERROR)
@app.before_request
def check_shutdown():
global shutdown_flag
if shutdown_flag:
print('server shutdown process')
focus_browser_and_send_shutdown_shortcut()
# サーバーを停止する処理
time.sleep(10)
os._exit(0)
return
# 通信は以下のような方法で行われる
# Google Colabから10秒に一回「*****REQUEST*****」が送られる
# もしキーボード入力があった場合には、プロンプトデータ+キーボードデータをプロンプトとして送信。なければ「*****EMPTY*****」を返信してidle状態を続ける
# Google colabは「*****EMPTY*****」なら10秒に一回のポーリングを再開。それ以外なら受信データをプロンプトとしてAIが返答生成する
# Google colabからの返信が「*****REQUEST*****」以外ならAIからのチャット返信として処理
def receive_data_analyze(receive_data):
global chat_log,user_input,user_input_stop_flag
# prompt生成
prompt = chat_log.replace('里穂: ','ASSISTANT: 里穂: ').replace('英樹: ','USER: 英樹: ') + 'ASSISTANT: '
if '*****REQUEST*****' in receive_data: # Google colabが「*****REQUEST*****」を送信してきて、
if not user_input_stop_flag: # chat_inputがNull(キー入力なし)なら、
return_data = '*****EMPTY*****' # チャット入力「*****EMPTY*****」を返信
else:
return_data = system_prompt + prompt # そうでない場合には、プロンプト入力を送信
else: # Google colabが「*****REQUEST*****」以外を送信してきたときは、
if '里穂:' in receive_data: # 里穂の対話の最初を抽出
chat_log += receive_data.split('\n')[0] + '\n' # 里穂の対話を追加して
print()
print(chat_log, end = '')
print('英樹: ', end = '')
user_input_stop_flag = False
return_data = '*****EMPTY*****' # idle状態に戻る
else: # 里穂の名前が最初になければ、リトライ
print('NO NAME: RETRY')
return_data = system_prompt + prompt
return return_data
def listen_for_input():
global user_input,chat_log,shutdown_flag, user_input_stop_flag
while True:
if user_input_stop_flag:
time.sleep(1)
else:
user_input = input()
if user_input == '終了': # 終了と入力されたら、shutdown_flagを立てる
shutdown_flag = True
break
else:
chat_log += '英樹: ' + user_input + '\n' # それ以外はchat_logに追記する
user_input_stop_flag = True
if __name__ == '__main__':
input_thread = threading.Thread(target=listen_for_input)
input_thread.daemon = True # メインスレッドが終了したらこのスレッドも終了する
input_thread.start()
app.run(host='0.0.0.0', port=8080)
これがリアルタイムの動画
所感
このソフトは途中段階であるので、UIの出来やローカルPCからのGoogle ColabのShutdownでエラーが出るなど、出来は悪い。
また私はGoogle colab Proを使っているが、適当に遊ぶ程度(例えば30分程度とか)ならば無料版でも楽しめることがポイントだ。
ここからさらにシステムとして改善していく所存だ。
例えば「記憶」を作る、喘ぎ声の個性を持たせる、ストーリー性を持たせる、などだ。
これらの実現のため、プロンプトを変化させながらLLMに話させ、本格的エロチャットAIを目指そうと思っている。
追記
数日後に動かすと、GPU設定しているのにも関わらずGPUが動作しない。
よくわからんが、llama-cpp-pythonのVersionを上げてみたら、復活。
なぜだ?
#!python -m pip install llama-cpp-python==0.2.77 --prefer-binary --extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cu122
!python -m pip install llama-cpp-python==0.2.87 --prefer-binary --extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cu122
この記事が気に入ったらサポートをしてみませんか?