60歳からの新しい挑戦に回答する「シニア起業家お助け隊」を作った話

************

こちらの「シニア起業家お助け隊」は社会貢献活動の一環として当事務所で作成しました。

シニアの方が起業したときに様々な問題を解決できるように、ChatGPTのGPTsを使って制作してあります。

利用はもちろん無料です。ご自由にお使いください。

シニア起業家お助け隊のURLはこちら
https://chatgpt.com/g/g-68848d2aa3b88191a6d66bdcc7c39afa-sinia-60sui-dai-yi-shang-qi-ye-jia-ozhu-kedui

***************

***************

シニア世代の“第二の人生”が注目される時代

人生100年時代と言われる今、60歳や70歳を過ぎてから新しい挑戦に踏み出す方が増えています。

「もう一度、自分の夢を形にしたい」「これまでの経験や人脈を活かして社会に貢献したい」と考えるシニア世代の起業家は年々増加傾向にあります。

しかし、実際に起業するとなると「何から始めたらいいかわからない」「経営の経験がない」「デジタルやITが苦手で不安」といった悩みやハードルも少なくありません。

若い世代とは違う人生経験や価値観を持つシニアの方が、安心して一歩を踏み出せる支援が求められています。

シニア起業家の悩みに寄り添うAIアドバイザー

こうした課題を解決する新サービスが「シニア起業家お助け隊」です。
(もちろん無料です)

シニア起業家お助け隊のURLはこちら
https://chatgpt.com/g/g-68848d2aa3b88191a6d66bdcc7c39afa-sinia-60sui-dai-yi-shang-qi-ye-jia-ozhu-kedui

わかりやすく、黒画面で表示
わかりやすく、黒画面で表示

このサービスは、OpenAIが提供するAI(人工知能)技術を活用し、シニア世代の方が起業やビジネス運営で抱えがちな悩みにやさしく丁寧に答えてくれるAIアドバイザーです。

たとえば、

「資金調達の方法は?」
「集客やSNSの使い方がわからない」
「経理や帳簿の管理が難しい」
「やりがいや生きがいを感じるには?」
など、経営のあらゆる疑問や不安に対応します。

しかも、専門用語はできるだけ使わず、わかりやすく説明。励ましや安心感を大切に。シニアならではの強み(人脈・経験・信頼)を活かすアドバイスにこだわっています。

デジタルが苦手でも大丈夫。やさしい言葉で何度でも相談OK

AIって難しそう、パソコンやスマホが苦手でも大丈夫?と心配される方もいるかもしれません。

でも、シニア起業家お助け隊は、LINEやチャット感覚で使えるので、特別なスキルや難しい操作は必要ありません。

質問内容も自由。ビジネスに限らず、人間関係の悩みや日々のちょっとした疑問など、幅広くサポートできます。

たとえば、

自分に合うビジネスアイデアは?
集客に役立つSNSの使い方を簡単に知りたい
お金の管理をシンプルにするコツは?
といった身近な相談から、失敗したときの立ち直り方まで、やさしく寄り添ってくれます。

わかりやすく、黒画面で表示

シニア起業の強みを活かせるアドバイスが充実

このサービスが他と違うのは、人生経験豊富なシニアの強みに着目していることです。

たとえば長年培ってきた人脈、誠実な対応、豊かな人生経験は、若い起業家にはない大きな武器です。

シニア起業家お助け隊は、そうした強みを活かしたビジネス戦略や、社会貢献につながるアイデアのアドバイスも得意としています。

自分の経験を活かせる場が欲しい、地域や仲間に役立つことをしたい、そんな思いにも力強く応えてくれます。

使い方はとてもカンタン!

1. GPTストアなどから「シニア起業家お助け隊」にアクセス
(⚫︎面倒な方は、下記のURLをクリック)
2. 相談したい内容をチャットで入力
3. AIが、あなたにぴったりのアドバイスをやさしい言葉で返してくれる

もし難しい操作があれば、家族や知り合いの方に最初だけサポートしてもらってもOK。
一度使い方がわかれば、あとは気軽にいつでも何度でも相談できます。

⚫︎シニア起業家お助け隊のURLはこちら
https://chatgpt.com/g/g-68848d2aa3b88191a6d66bdcc7c39afa-sinia-60sui-dai-yi-shang-qi-ye-jia-ozhu-kedui

まとめ 誰でも、何歳からでも夢を叶えられる時代へ

シニア世代の起業は、社会や地域をもっと元気にしてくれる可能性にあふれています。

やってみたいけど不安、自分にできるか心配、そんな方もAIアドバイザーの力を借りて、ぜひ一歩踏み出してみてください。

シニア起業家お助け隊は、あなたの経験と情熱を、ビジネスという新しい形で輝かせるお手伝いをします。

第二の人生、思い切り楽しみましょう!

DGM × MIT SEALでつくるハイブリッド自己進化型AIを試した話 実験版

*********

この辺りの内容は、これから生成AIを学びたい学生さんや若手のAI初心者さんに捧げます。
これからのAI時代を作っていくのはあなた方です。
プログラミングのPythonを習得して、興味が出てきたらAI関連の本や記事を読み進めてください。
いつでも好奇心をもって、コードを実装して試してください。
さすればきっと、AIがあなたの力になる日が来るでしょう。

ASI (Artificial Super Intelligence、超知能) が人類の課題を解決してくれる日を信じて。

*********

AIが自ら進化する時代へ

今、AI業界では「AIが自分自身を進化させる」というテーマが急速に注目を集めています。
従来は、人間が手作業でAIのアルゴリズムや設定を調整していました。しかし最近では、AIが自分で「もっと良い方法はないか」と考え、試行錯誤しながら成長していく時代が現実になろうとしています。

この流れの最先端を走るのが、日本発のSakana AIによる「ダーウィン・ゲーデルマシン(DGM)」と、アメリカ・MITが開発した「SEAL(Self-Evolving Agent with LoRA)」という二つの自己進化AI技術です。

今回、この二つを組み合わせ、「ハイブリッド自己進化型AI」を実験しました。
その過程でわかった“AIが進化するための条件”について、お伝えします。

DGMとSEAL、2つの自己進化AI技術の概要

まずDGMとSEALの仕組みについて簡単に説明します。

■ DGM(ダーウィン・ゲーデルマシン)

DGMの最大の特徴は「AIが自分自身のプログラムを書き換えて改善できる」点です。
まるで生物が進化するように、AI自身が新しいアルゴリズムを考え、実際にプログラムを修正して性能を向上させます。

■ SEAL(Self-Evolving Agent with LoRA)

SEALは、「新しいやり方を学習して試し、成果を評価して、さらに進化する」というサイクルを自律的に繰り返すAIです。
MITが開発したこの仕組みは、AIが新たなスキルや知識を次々と身につけていく“自己進化”を実現しています。

実験の流れ DGM × SEALのハイブリッド構成

この2つの仕組みの“良いとこ取り”をして、DGMが「より良い方法(ワークフロー)」をAIに提案し、SEALがそれを学習・評価して自己進化するという流れを目指しました。

役割分担

*DGM役(改善案の提案)
 今回はSakana AIのDGMの役割を、GPT-3.5というAIチャットボットに任せました。
 「このタスク、どうすれば効率的にできる?」とGPTに問いかけ、Pythonのコード(ワークフロー)を生成してもらいます。

* SEAL役(学習&評価)
 SEALの役割は、日本語が得意な軽量AI「TinySwallow-1.5B-Instruct」に担当してもらいます。
 GPTが考えた新しいワークフローをTinySwallowが学習し、その性能を評価する、という構成です。

実験テーマ「足し算」を言語AIにやらせてみる

どんなタスクでハイブリッド自己進化AIを試すかですが、今回はあえて「足し算」という言語AIにとって専門外のテーマを選びました。
もともとTinySwallow-1.5B-Instructは数学も結構学習しているみたいで、簡単な計算問題は解けるモデルですが、さて、どうなるかです。

タスク例

入力「5 + 8」
正解「13」

本来、日本語テキストを理解することが得意なTinySwallowに、「DGM(GPT-3.5)」が出したプログラムを使って計算タスクを学ばせ、その効果を確かめます。

実験結果 DGMの提案は完璧、でもSEALは学習できず

最初にDGM役のGPT-3.5が出したPythonコードは、それなりなものでした。

python
lambda text: str(sum(map(int, text.split(‘+’))))

足し算のコードですね。
このコードがあれば、「5 + 8」などの計算を自動で処理できます。

そこで、このワークフローをTinySwallowに学習させてみました。
「入力が“13”なら、そのまま“13”と返すだけ」という極めて単純な学習タスクのはずでした。

しかし、実際にTinySwallowに学習させてテストしたところ「13」に対して「27」など、全く違う数字を返しました。

なぜ失敗したのか? ファインチューニングとデータ量の本質

この原因を理解するには、「AIの学習」を人間の勉強に例えるのが分かりやすいです。

事前学習(巨大な図書館を読破)

TinySwallowは、事前学習の段階でインターネット上の膨大な日本語テキストを読んでいます。
まるで巨大な図書館の本を全て読んだかのように、知識は豊富です。
ただし、その知識の中に計算ルールが入っていたのかは定かではありません。

ファインチューニング(4枚の単語カード)

今回の実験で用意した足し算の学習データは、たった「4行」だけ。
これは、いくら頭の良い学生でも試験前日に4枚の単語カードを渡され、「これで計算をマスターしろ」と言われるようなものです。

(今回は流れを知るのが目的なので、実際は数千から万単位のデータを揃えたいところです)

推論(試験本番)

もし本番で「10 + 10」という新しい問題が出たらどうなるでしょうか?
足し算のルールを身につけていないと仮定すると、TinySwallowは自分の得意なことの「自然な日本語の文章を生成する」ことに頼ってしまいます。

これが、TinySwallowが「計算結果」ではなく「Here’s the calculation:」や「## ステップ」などの文章を返した理由だと思われます。

どれだけのデータが必要なのか?

AIに新しいスキルをしっかり身につけさせるには、通常「数百〜数千、場合によっては数万件」の多様なデータが必要です。
たとえば「足し算」なら、下記のような様々な組み合わせの例を数多く見せる必要があります。

* 1 + 1 = 2
* 10 + 25 = 35
* 123 + 456 = 579
* 99 + 0 = 99
* など、桁数や数字のパターンが異なる大量の例

こうして初めて、AIは「+記号は両側の数値を足す」というルールを抽象的に学び始めます。

実験でわかった“条件”とは

今回の実験で得た最大の教訓は、「AIの自己進化」には3つの要素(今回の場合)がすべて揃う必要があるということです。

1. DGM(提案AI)の能力
 いくらDGM(コーチ)が完璧な作戦を立てても、

2. SEAL(学習AI)の専門性や適性
 その作戦を実行するSEAL(選手)がタスクに根本的に向いていなければ、

3. 十分な学習データの質と量
 さらに練習量(ファインチューニングデータ)が圧倒的に不足していれば、

自己進化のサイクルは機能しません。

まとめ AI自己進化に必要なもの

今回の実験は、「AIがAIを進化させる」という夢の実現に向けて、まだ課題があることを教えてくれました。

今回のハイブリッド自己進化システムは、「DGM(戦略担当)」・「SEAL(現場担当)」・「十分なデータ(練習量)」の三位一体で成り立ちます。

どれか1つでも欠けてしまうと、進化のサイクルは止まってしまいます。

技術やアイデアだけではなく、地道なデータ作りやモデルごとの専門性も不可欠です。

「AIがAIを進化させる世界」は確実に近づいていますが、その実現には“データの力”と“モデル同士の相性”も考慮する必要があるかと。

今回のDGMとSEALを使ったハイブリッド自己進化型の実験からは、「提案力・学習能力・十分なデータ」この3つが揃って初めて、進化させられることを教えてくれました。

それ以外にも今後の実験と通して、第4、第5のルールが出てくるかも知れません。
そんな発見もまた楽しいものです。

⚫︎実験につかった pythonコード

最後にコードを貼っておきます。ご自由にお使いください。
わかりやすいようにコメントをこまめに書いてあります.

なお、GPTのAPI料金がかかります。
そこのコードを改変すれば無料でできます。
(コードの使用は自己責任でお願いします)

# ==============================================================================
# 1. 必要ライブラリのインストール
# ==============================================================================
!pip install -q transformers peft bitsandbytes openai accelerate huggingface_hub

print("✅ ライブラリのインストールが完了しました。")


# ==============================================================================
# 2. 初期設定(Driveマウント、APIキー入力)
# ==============================================================================
import os
import torch
from huggingface_hub import login, snapshot_download

# --- Google Driveのマウント ---
from google.colab import drive
print("🔐 Google Driveをマウントします。認証を行ってください...")
drive.mount('/content/drive', force_remount=True)
print("✅ Google Driveのマウントが完了しました!")

print("\n--- APIキーとトークンの入力 ---")
# --- Hugging Face トークンの入力 ---
hf_token = input("\n>>> Hugging Faceのアクセストークンを貼り付けてEnterキーを押してください: ").strip()
if not hf_token: raise ValueError("❌ Hugging Faceのアクセストークンが入力されませんでした。")
# --- OpenAI APIキーの入力 ---
openai_api_key = input("\n>>> OpenAIのAPIキーを貼り付けてください: ").strip()
if not openai_api_key: raise ValueError("❌ OpenAIのAPIキーが入力されませんでした。")
os.environ["OPENAI_API_KEY"] = openai_api_key
print("✅ OpenAI APIキーを環境変数に設定しました。")
# --- GPUの利用可能性を確認 ---
if not torch.cuda.is_available(): print("⚠️ 警告: GPUが利用できません。")
else: print(f"✅ GPUが利用可能です。デバイス: {torch.cuda.get_device_name(0)}")


# ==============================================================================
# 3. モデルの準備(初回のみダウンロード、2回目以降はスキップ)
# ==============================================================================
print("\n" + "="*60)
print("=== モデルの準備を開始します ===")
print("="*60)
model_name_on_hf = "SakanaAI/TinySwallow-1.5B-Instruct"
local_model_path = "/content/drive/MyDrive/ColabModels/tiny-swallow-v3"
print(f"モデルの保存/読込パス: {local_model_path}")
config_path = os.path.join(local_model_path, "config.json")
if os.path.exists(config_path):
    print(f"✅ モデルは既に存在します。ダウンロードをスキップします。")
else:
    print(f"⚠️ モデルが見つかりません。ダウンロードを開始します...")
    login(token=hf_token)
    snapshot_download(repo_id=model_name_on_hf, local_dir=local_model_path, token=hf_token)
    print(f"✅ モデルのダウンロードが完了しました! → '{local_model_path}'")


# ==============================================================================
# 4. SEAL: モデルをローカルからロードして自己学習するクラス (公式作法対応)
# ==============================================================================
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig, TrainingArguments, Trainer
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training

class SEAL_TinySwallow:
    def __init__(self, model_path: str):
        print(f"\n[SEAL] ローカルパス '{model_path}' からモデルをロードします...")
        bnb_config = BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_quant_type='nf4', bnb_4bit_compute_dtype=torch.bfloat16)
        self.tokenizer = AutoTokenizer.from_pretrained(model_path)
        base_model = AutoModelForCausalLM.from_pretrained(model_path, quantization_config=bnb_config, device_map="auto")
        base_model = prepare_model_for_kbit_training(base_model)
        lora_config = LoraConfig(r=16, lora_alpha=32, target_modules=["q_proj", "v_proj"], lora_dropout=0.05, bias="none", task_type="CAUSAL_LM")
        self.model = get_peft_model(base_model, lora_config)
        self.model.eval()
        print(f"✅ [SEAL] ローカルモデル ({model_path}) の準備が完了しました!")

    def finetune_on_feedback(self, prompts: list, targets: list):
        print("\n[SEAL] フィードバックに基づくファインチューニングを開始します...")
        
        # ★★★【最重要改善点】学習データを公式チャット形式に変換 ★★★
        messages_list = []
        for p, t in zip(prompts, targets):
            messages = [
                {"role": "system", "content": "あなたは与えられた数式を計算するアシスタントです。"},
                {"role": "user", "content": p},
                {"role": "assistant", "content": t}
            ]
            messages_list.append(messages)
        full_prompts = [self.tokenizer.apply_chat_template(msg, tokenize=False, add_generation_prompt=False) for msg in messages_list]
        
        class SimpleDataset(torch.utils.data.Dataset):
            def __init__(self, full_prompts, tokenizer):
                self.encodings = tokenizer(full_prompts, truncation=True, padding=True, max_length=128, return_tensors="pt")
            def __len__(self): return len(self.encodings["input_ids"])
            def __getitem__(self, idx):
                item = {key: val[idx] for key, val in self.encodings.items()}
                item['labels'] = item['input_ids'].clone()
                return item
                
        dataset = SimpleDataset(full_prompts, self.tokenizer)
        args = TrainingArguments(
            output_dir='./results', num_train_epochs=1, per_device_train_batch_size=1,
            logging_steps=10, save_steps=20, learning_rate=1e-4, disable_tqdm=False,
            fp16=torch.cuda.is_available(), report_to="none",
        )
        self.model.train()
        trainer = Trainer(model=self.model, args=args, train_dataset=dataset)
        trainer.train()
        self.model.eval()
        print("✅ [SEAL] ファインチューニングが完了しました。")

    def generate(self, prompt: str, max_new_tokens: int = 5) -> str:
        # ★★★【最重要改善点】推論時も公式チャット形式を使用 ★★★
        messages = [
            {"role": "system", "content": "あなたは与えられた数式を計算するアシスタントです。"},
            {"role": "user", "content": prompt},
        ]
        input_ids = self.tokenizer.apply_chat_template(
            messages, add_generation_prompt=True, return_tensors="pt"
        ).to(self.model.device)
        
        terminators = [self.tokenizer.eos_token_id] + [
            self.tokenizer.convert_tokens_to_ids(token) for token in ["<|eot_id|>", "<|im_end|>"]
        ]
        valid_terminators = [term_id for term_id in terminators if term_id is not None]

        with torch.no_grad():
            output_ids = self.model.generate(
                input_ids, max_new_tokens=max_new_tokens, do_sample=False,
                eos_token_id=valid_terminators,
            )
        response_ids = output_ids[0][input_ids.shape[-1]:]
        return self.tokenizer.decode(response_ids, skip_special_tokens=True).strip()


# ==============================================================================
# 5. DGM: GPT-3.5-turboでワークフローを自動生成するクラス (変更なし)
# ==============================================================================
import openai
import re
class DGM_GPT:
    def __init__(self):
        self.client = openai.OpenAI(api_key=os.environ["OPENAI_API_KEY"])
        self.archive = []
    def propose_new_workflow(self, task_description: str, example_input: str):
        print("\n[DGM] gpt-3.5-turboに新しいワークフローの提案を依頼します...")
        prompt = ("あなたはPythonコード生成の専門家です。下記のタスクを解決するPythonの<code>lambda</code>式を1つだけ生成してください。\n"
                  "【タスク説明】\n" + task_description + "\n【入力例】\n" + example_input +
                  "\n【厳格な出力ルール】\n1. 出力は<code>lambda</code>で始まるコードのみとする。\n2. 説明、コメント、<code></code><code>python ... </code><code></code>のようなマークダウンは絶対に含めない。\n3. 1行で完結させること。\n"
                  "【出力例】\nlambda text: str(sum(map(int, text.split('+'))))")
        try:
            response = self.client.chat.completions.create(model="gpt-3.5-turbo", messages=[{"role": "user", "content": prompt}], temperature=0.7)
            content = response.choices[0].message.content.strip()
            match = re.search(r"lambda.*", content)
            if not match: raise ValueError("応答からlambda式が見つかりませんでした。")
            code_line = match.group(0)
            workflow_func = eval(code_line)
            print(f"✅ [DGM] ワークフロー提案を受信: {code_line}")
            return workflow_func, code_line
        except Exception as e:
            print(f"❌ [DGM] ワークフロー生成中にエラーが発生しました: {e}")
            print("   デフォルトのワークフローを使用します。")
            return eval("lambda text: text"), "lambda text: text"
    def archive_workflow(self, code_line: str, score: float):
        print(f"[DGM] ワークフロー '{code_line}' のスコア {score:.2f} を記録しました。")
        self.archive.append((code_line, score))

# ==============================================================================
# 6. ハイブリッド自己進化デモの実行 (変更なし)
# ==============================================================================
print("\n" + "="*60)
print("=== ハイブリッド自己進化デモ(足し算タスク)を開始します ===")
print("="*60)
seal = SEAL_TinySwallow(model_path=local_model_path)
dgm = DGM_GPT()
texts   = ["5 + 8", "12 + 7", "3 + 15", "9 + 9"]
targets = ["13",    "19",     "18",     "18"]
task_desc = "与えられた 'a + b' 形式の文字列を計算し、結果を文字列として返すタスク。"
num_generations = 2
for i in range(num_generations):
    print(f"\n\n--- GENERATION {i+1}/{num_generations} ---")
    workflow_func, code_line = dgm.propose_new_workflow(task_desc, texts[0])
    workflowed_texts = [workflow_func(t) for t in texts]
    seal.finetune_on_feedback(workflowed_texts, targets)
    
    print("\n[EVAL] 学習後のモデル性能を評価します...")
    correct_count = 0
    for inp_text, target_text in zip(workflowed_texts, targets):
        generated_text = seal.generate(inp_text)
        print(f"  - Input:     '{inp_text}'")
        print(f"  - Generated: '{generated_text}'")
        print(f"  - Target:    '{target_text}'")
        if generated_text.strip() == target_text.strip():
            correct_count += 1
            print("    -> ✅ Correct")
        else:
            print("    -> ❌ Incorrect")
            
    accuracy = correct_count / len(texts)
    print(f"✅ [EVAL] 評価完了。Accuracy after SEAL adaptation: {accuracy:.2f}")
    dgm.archive_workflow(code_line, accuracy)

print("\n\n" + "="*60)
print("=== 自己進化ループ完了:最終結果 ===")
print("="*60)
if dgm.archive:
    best_code_line, best_acc = max(dgm.archive, key=lambda item: item[1])
    print(f"🏆 最も性能の良かったワークフロー (gpt-3.5-turbo提案):")
    print(f"   コード: {best_code_line}")
    print(f"   精度: {best_acc:.2f}")
else:
    print("ワークフローが一つも生成されませんでした。")


****************

最近のデジタルアート作品を掲載!

X 旧ツイッターもやってます。
https://x.com/ison1232

インスタグラムはこちら
https://www.instagram.com/nanahati555/

****************

LLM(大規模言語モデル)を教師モデルにして、小規模言語モデルに蒸留した話 実験版

DeepSeekの登場以来、「蒸留」という言葉が結構流行ってきましたね。

蒸留とは

蒸留(distillation) とは、
「大きくて高性能な教師モデルの知識を、小さくて軽量な生徒モデルに効率的に移す技術」
のことを指します。

元々は自然言語処理などの分野で、巨大モデルをそのままデバイスに載せるのは難しいため、
・教師モデルが出す出力(予測確率など)
・中間層の特徴量
を利用して、生徒モデルに教師モデルの「ふるまい」を学ばせる仕組みとして考えられました。

蒸留のポイントは、
・小さいモデル(生徒モデル)が教師の出力分布を真似る
・教師の持つパターン認識や知識を圧縮して伝える
・学習データが少なくても、教師の知識を最大限引き継げる
といったところです。

蒸留に使うモデルはこれだ

今までは高額なお金をかけて(GPUなど)学習していくと言う感じでしたが、この蒸留と言う手法を使えば、比較的手軽に専門領域に特化した小規模言語モデルを構築することができます

今回は、この蒸留の手法を使って、Googleコラボ上(有料版)で全て完結できるように、小さいスペックのモデルを使って実験してみたいと思います

まず、今回選ばれたモデルは
SakanaAIさんが公開している言語モデル TinySwallow-1.5B-Instructです。

通常の7B以上とかのモデルだと大きすぎてコラボにうまく載せられません。
そこで性能のいい大規模言語モデルのTinySwallow-1.5Bを選択しました。

このモデルを教師モデルにして、いわゆる生徒モデルもTinySwallow-1.5Bを使って、「空の生徒モデル」を構築し、そこに知識を蒸留(distillation)していくプロセスを試しました。

教師モデルの準備

まずは教師役のモデル、
SakanaAI/TinySwallow-1.5B-Instruct
を使います。

パラメータ数は約 1.54B(15億パラメータ) で、推論能力に優れたインストラクション・フォロー型のLLMです。

このモデルはHugging Face上に公開されており、まずColabへダウンロードしました。

モデル本体(model.safetensors)、トークナイザーの設定ファイル、その他メタデータまで合わせて14ファイル。
容量としてはおおむね3GB超ですが、2回目以降のキャッシュが効くため実質的には快適に動きます。

生徒モデルの構築

次に、生徒モデルをTinySwallow-1.5Bで「空の状態」から作ります。

ここでいう「空」とは、重みをほとんど初期化状態にして、教師の動きを真似させるところから始めることです。

構築した生徒モデルは およそ108Mパラメータ。
これは教師の約1/14ほどのサイズで、とても軽量です。

蒸留の流れとLossの推移

ここから教師モデルの出力をガイドにして、生徒モデルに学習させます。

やり方としては教師モデルの出力ロジットを教師信号として、損失関数にKLダイバージェンスなどを適用して生徒モデルを収束させていく形を取ります。

いわゆる Knowledge Distillation の定番手法です。

今回は以下の条件で蒸留を走らせました。

学習回数:10エポック

Optimizer:Adam

学習率:調整済

損失関数:教師出力との距離を最小化

実際のLossの推移はこんな感じです。

Epoch 1/10 – Loss: 13.1150
Epoch 2/10 – Loss: 12.8502

Epoch 10/10 – Loss: 11.9068

Lossはゆるやかに減少しており、少なくとも教師のふるまいを表面的には学習できるところまで進んでいるように見えました。

簡易テキスト生成のテスト

学習が終わったところで、生徒モデルのテキスト生成能力をテストしました。
(最終エポックでロスが11以上あるので、それなりの回答を想定)

プロンプトとして
「昔々あるところに、」
を入力してみたところ、生成結果は以下の通り。

昔々あるところに、thenReturn matière’),
sent_AP-directory Caucasian UserData\Active نوف UserData剑 nrparer買う-directoryFinoxious lanes.a比利 apenas要坚持_APB foo딛食べて剑 grants临近小额贷款 UFO apenas-directoryDiese depparer atIndexparermov SeiteDis fooموظ

正直なところ、単語が多言語混在で意味不明気味です。

しかしこれは想定内で、まずまずオッケーと言ったところです。

理由としては、学習データが非常に少量だったことが主因で、文章の一貫性を持たせるほどの蒸留は進んでいないです。

とはいえパラメータ108Mという極小モデルに10エポックだけでここまで出力させるのは、それなりに面白い成果ともいえます。

まとめと今後の課題

今回の取り組みは

・教師モデルに小さめの大規模言語モデル(TinySwallow-1.5B)を使用
・そこからさらに桁違いに小さい生徒モデル(108M)を作る
・生徒は初期化状態から蒸留で構築する

という実験でした。

結果としては、プロンプトに対して「なんらかの言葉を返せる」レベルには到達しました。

より本格的にかつ専門領域に特化した蒸留を行うなら

・教師モデルの出力を使って大量のペアデータを生成
・なおかつ専門性の高い、質の良いデータを揃える
・学習エポックを増やす

などの工夫が不可欠です。

もっと大きなモデルでやりたければ、AWSなどを使って、中堅の大規模言語モデルを教師モデルとし、小規模言語モデルへ蒸留していけば、結構いい感じの小型モデルの構築が可能です。

さて今回は「とにかく空のモデルからコラボでサクッと蒸留する」というチャレンジでしたが、技術的におもしろい試みでした。

今後はもう少しデータを増やして、専門特化した小型の言語モデルを作ってみたいと思います。

(とはいえ、数十万件のデータそろえるのはちょっとなあ…。1万件くらいならいけるかなあ。
ゴルフ専用モデル、アート専用モデルとか作りたいよなあ)

****************

最近のデジタルアート作品を掲載!

X 旧ツイッターもやってます。
https://x.com/ison1232

インスタグラムはこちら
https://www.instagram.com/nanahati555/

****************

PAGE TOP