3
3

小さな日本語GPTのエンジニアリング。僕だけの日本語GPTを作るというゲーム。

Last updated at Posted at 2024-09-01

前回のあらすじ。

image.png

Google corab GPU で実行です。

実行結果。日本語トークナイザーと日本語モデルを使用。

生成されたテキスト: エポック75

Generated Text: 健一の次の挑戦は、aiの可能性をさらに探求することでした。 田中健一は、新しいaiモデルの設計のアイデアに興奮しました。 彼は二次元テンソルを掛け合わせることで、これまで不可能とされていたものを実現でき、しかも、それが瞬時に実現できることに確信しました。

Generated Text: 健一の次の挑戦は、aiの可能性をさらに探求することでした。 四次元テンソルを使用した計算は、オイラーシャフト と gutmf (gut (g) ) の領域外に落下させて、結果をベクトルに埋め込み、結果をキャンバスに描画するといった高度なaiの計算プロセスでした。 四次元テンソルを使用した計算は、計算の過程においてテンソルの重みに耐えるのが難しかった。 再挑戦の挑戦は、aiの能力が開花するのが近づいたことを感じながら、彼は考えました。 円滑化した後、彼はアイデアを試しながら、新しい計算モデルの設計を始めました。 それは、単純なテンソルの掛け算でした。 テンソルの掛け算は、彼の最初の挑戦でした。 彼は、その挑戦のために四次元テンソルの新しい計算プロセスのアイデアが浮かびました。 彼は、テンソルの新しい計算で表現された言語モデルのアイデアに興奮しました。 彼は、三次元テンソルの

生成されたテキスト: エポック300

Generated Text:健一の次の挑戦は、aiの可能性をさらに探求することでした。のうち、第3代および第4代はサルトル、第5代はマニピュレーターという、四次元テンソルを掛け合わせることで、四次元テンソルを埋め込む計算のコードを生成しました。 このコードがaiの本質であることに気づきました。 nwkは三次元テンソルに埋め込まれており、これがaiの高度な知識と理解を支えていることに気づきました。

スクリーンショット 2024-09-02 073258.png

# 必要なライブラリのインストール
!pip install datasets transformers

from datasets import load_dataset
from transformers import Trainer, TrainingArguments, AutoTokenizer, AutoModelForCausalLM
import torch

# 日本語トレーニングテキスト
training_text_ja = """
田中健一は東京の中心部に住むプログラマーで、言語モデル用のAIを開発するスタートアップ企業でエンジニアとして働いていました。彼の仕事は毎日複雑なアルゴリズムやデータ処理に囲まれており、言語モデルが知識を構築し自然言語を生成する過程について深く探求していました。ある日、健一はプロジェクトの一環として四次元テンソルを使用した新しい計算モデルの設計を任されました。それまで彼は二次元および三次元テンソルを扱っていましたが、四次元テンソルは未知の領域でした。テンソルの深さに魅了された彼は、その挑戦を受けることに決めました。

健一は言語モデルの計算プロセスについて考えました。単語はベクトルに埋め込まれ、これらのベクトルは行列を形成するためにリンクされます。さらに、複数の行列がリンクされて三次元テンソルが形成されます。それから、これらの三次元テンソルを掛け合わせることで、コンテキストテンソルが得られ、そこから意味のある行列を抽出できます。この行列をテキストに変換することで、言語モデルの応答が得られます。健一は、この単純なテンソルの掛け算が言語モデルの本質であることに気づきました。

さらに、健一はMOE(Mixture of Experts)という新しいAIモデルのアイデアに興奮しました。MOEでは、一つのAIの中に複数の専門家が存在し、それぞれが独自の専門知識を持っています。これを実現するためには、四次元テンソルを掛け合わせることで、各専門家が異なる視点から情報を処理できるようになります。これによりAIの理解力が飛躍的に向上します。

健一は三次元テンソルを使用した計算のコードを書き終え、結果をキャンバスに描画するプログラムを実装しました。彼はテンソル計算で表現された言語モデルを構築し、テキストを生成しました。テンソル計算が言語モデルの核心であることを再確認し、これが深いAI理解の実現への道を開くと確信しました。仕事を終えた後、健一は東京の夜の街を歩き、再び自分の仕事の重要性を感じました。テンソル計算は単なる数値の操作に過ぎないように見えるかもしれませんが、それがAIの高度な知識と理解を支えていることに気づきました。テンソルの向こうにある無限の可能性を感じながら、彼は次の挑戦のために新しいコードの執筆を始めました。
"""

# トレーニングテキストをファイルに保存
with open("training_text_ja.txt", "w") as f:
    f.write(training_text_ja)

# モデルとトークナイザーの準備
model_name = "rinna/japanese-gpt2-small"
tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=False)
tokenizer.do_lower_case = True

model = AutoModelForCausalLM.from_pretrained(model_name)

# データセットの作成
dataset = load_dataset("text", data_files={"train": "training_text_ja.txt"})

def tokenize_function(examples):
    # トークン化し、input_idsとattention_maskを生成
    tokenized_output = tokenizer(examples["text"], padding="max_length", truncation=True, max_length=512)
    # labelsをinput_idsとして設定
    tokenized_output["labels"] = tokenized_output["input_ids"].copy()
    return tokenized_output

# データセットのトークン化
tokenized_datasets = dataset.map(tokenize_function, batched=True, remove_columns=["text"])

# PyTorchテンソルとしてデータを返すように設定
tokenized_datasets.set_format("torch", columns=["input_ids", "attention_mask", "labels"])

# トレーニングの引数設定
training_args = TrainingArguments(
    output_dir="./results",
    evaluation_strategy="steps",
    eval_steps=500,
    logging_steps=100,
    save_steps=500,
    num_train_epochs=75,
    per_device_train_batch_size=2,
    per_device_eval_batch_size=2,
    warmup_steps=500,
    weight_decay=0.01,
    logging_dir="./logs",
)

# Trainerオブジェクトの作成
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["train"],
)

# トレーニングの実行
trainer.train()

# トレーニング済みモデルの保存
model.save_pretrained("./trained_model")
tokenizer.save_pretrained("./trained_model")

# テキスト生成
#prompt_text = "健一の次の挑戦は、AIの可能性をさらに探求することでした。"
#input_ids = tokenizer.encode(prompt_text, return_tensors='pt')

# モデルのデバイスを取得
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)

# `input_ids`をモデルと同じデバイスに移動
input_ids = input_ids.to(device)

# テキスト生成
input_text = "健一の次の挑戦は、AIの可能性をさらに探求することでした。"
inputs = tokenizer(input_text, return_tensors="pt")

# データをCUDAデバイスに移動
inputs = {key: value.to('cuda') for key, value in inputs.items()}

# テキスト生成の設定
output = model.generate(
    **inputs,
    max_length=200,  # 最大生成長
    min_length=20,   # 最小生成長
    do_sample=True,  # サンプリングを使用
    top_k=50,        # top_kサンプリングの設定
    top_p=0.95,      # nucleusサンプリングの設定
    pad_token_id=tokenizer.eos_token_id
)

generated_text = tokenizer.decode(output[0], skip_special_tokens=True)
print("Generated Text:", generated_text)

image.png

!pip install gradio
import gradio as gr

def generate_text(prompt):
    # モデルのデバイスを取得
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    model.to(device)

    # テキスト生成
    inputs = tokenizer(prompt, return_tensors="pt")

    # データをCUDAデバイスに移動
    inputs = {key: value.to(device) for key, value in inputs.items()}

    # テキスト生成の設定
    output = model.generate(
        **inputs,
        max_length=200,  # 最大生成長
        min_length=20,   # 最小生成長
        do_sample=True,  # サンプリングを使用
        top_k=50,        # top_kサンプリングの設定
        top_p=0.95,      # nucleusサンプリングの設定
        pad_token_id=tokenizer.eos_token_id
    )

    generated_text = tokenizer.decode(output[0], skip_special_tokens=True)
    return generated_text

# Gradioインターフェースの設定
interface = gr.Interface(
    fn=generate_text,
    inputs=gr.Textbox(label="入力プロンプト", placeholder="ここにプロンプトを入力してください..."),
    outputs=gr.Textbox(label="生成されたテキスト"),
    title="テキスト生成モデル",
    description="このインターフェースは、日本語のプロンプトに基づいてテキストを生成します。",
)

# インターフェースの起動
interface.launch()

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3