1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SLMを使って同じミスをしない様なメモアプリを作ってみた!

Posted at

はじめに

初めましての人もそうでない人もこんにちは!

皆さんは同じミスを最大何回まで繰り返したことがありますか?
私は最低でも7回以上も同じ様なミスを繰り返した記憶があります...
メモを取ればいいと思いますが後から読み返そうとすると字が汚すぎて後から読めたものではないんですよね
また、自分で書いといてどういう意味かわからない場合もあったりするなど手書きでミスをメモするのって個人的にあまり向いてないんですよね。
しかし、PCであれば誰でもみやすいですし最近だと生成AIが出てきたおかげで拙い文章でもきちんと意味がわかる様な文章になるなど私にとってメモを取る環境が変わってきている様に感じます!

そこで今回は小規模言語モデル(SLM)を用いたミスチェック用メモアプリを作ってみたのでぜひ最後までご覧ください!

小規模言語モデル(SLM)とは

皆さんは小規模言語モデルを聞いたことはありますか?
おそらくLLMは知っているけどSLMは知らないって人は一定数いると思います!
SLMを簡単に説明するとLLMよりも回答精度は悪いが非常に軽く素早い回答を生成することができる言語モデルのことです!
SLMはパラメータ数が数億から数百億程度と比較的小さく設計されており、LLMは数千億から数兆のパラメータで設計されています!
学習量が全く違うため複雑な推論や創作能力では劣りますが、単純な文章を生成する上ではあまり問題はないかと思います!

SLMが向いているところ・今回使用する理由

今回技術選定としてSLMを使用する背景にもつながりますが一つ目の理由としてLLMを使用する様な高性能なGPUを用意しなくて大丈夫という点です!二つ目は今回の様なアプリであればLLMの様な高性能なものでなくても問題がないということです!単純な回答の生成で素早く回答することが大事だと考えSLMを使用しました!

今回作るもの

学業や仕事、実際に指摘されたミスを入力する。小規模言語モデルであるphi-3を使って要約して見やすくすることで2回目以降の失敗を起こさない・軽減をすることができるwebアプリを作る。

作ってみた

技術構成

今回作成するアプリの技術構成はこんな感じです!

バックエンド

  • Python (FastAPI)
  • Phi-3-mini-4k-instruct (Microsoft製SLM)
  • SQLite

フロントエンド

  • React + TypeScript

ディレクトリ構成

miss_check/
├── backend/                 
│   ├── main.py
│   ├── model_manager.py    # Phi-3の管理
│   ├── database.py         # SQLite操作
│   ├── config.py           # 設定ファイル
│   └── requirements.txt    
└── frontend/               
    ├── src/
    │   ├── components/     # コンポーネント
    │   ├── hooks/
    │   └── services/       # API通信
    └── package.json

バックエンドの実装

まずはPhi-3モデルを管理するクラスから作っていきます!

# backend/model_manager.py
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
from huggingface_hub import snapshot_download

class ModelManager:
    def __init__(self):
        self.model = None
        self.tokenizer = None
        # GPUがあるなら使う、なかったらCPU
        self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    
    def load_model(self):
        try:
            # Phi-3モデルをダウンロード
            model_path = snapshot_download(
                repo_id="microsoft/phi-3-mini-4k-instruct",
                local_files_only=False,
            )
            
            self.tokenizer = AutoTokenizer.from_pretrained(
                model_path, trust_remote_code=True
            )
            
            # トークンの設定
            if self.tokenizer.pad_token is None:
                self.tokenizer.pad_token = self.tokenizer.eos_token
            
            # モデルの設定
            model_kwargs = {
                "trust_remote_code": True,
                "torch_dtype": torch.float16 if torch.cuda.is_available() else torch.float32,
            }
            
            if torch.cuda.is_available():
                model_kwargs["device_map"] = "auto"
            
            self.model = AutoModelForCausalLM.from_pretrained(
                model_path, **model_kwargs
            )
            
            print(f"モデルを{self.device}で読み込みました!")
            
        except Exception as e:
            print(f"モデル読み込みエラー: {e}")
            raise

初回実行時は2-3GBのモデルをダウンロードするので少し時間がかかります!

次に要約生成の部分です!

def generate_summary(self, text: str, max_length: int, min_length: int) -> str:
    # プロンプトを日本語で設計
    prompt = f"""以下のテキストを簡潔に要約してください。重要なポイントを含めながら、{min_length}文字以上{max_length}文字以下で要約してください。

テキスト: {text}

要約:"""

    inputs = self.tokenizer(
        prompt,
        return_tensors="pt",
        padding=True,
        truncation=True,
        max_length=2048  # Phi-3-mini-4kの制限
    )
    
    # GPUがあるならGPUに送る
    if torch.cuda.is_available():
        inputs = {k: v.to(self.model.device) for k, v in inputs.items()}
    
    # 要約生成
    with torch.no_grad():
        outputs = self.model.generate(
            **inputs,
            max_new_tokens=200,
            temperature=0.7,
            do_sample=True,
            repetition_penalty=1.1,
            top_p=0.9
        )
    
    generated_text = self.tokenizer.decode(outputs[0], skip_special_tokens=True)
    summary_start = generated_text.find("要約:") + 3
    summary = generated_text[summary_start:].strip()
    
    return summary

他にも色々実装した部分はありますが長くなるのでコード部分はこんな感じです!

実際に使ってみた感想

良かった点:

  • SLMでも十分実用的な要約ができる!
  • ローカルで動くのでプライバシーが守れる
  • API料金を気にしなくていい!

改善したい点:

  • 要約が短すぎることがある
  • 適切な要約がされない時がある
  • 初回起動が少し遅い

今後やりたいこと

  1. カテゴリ分類機能
    • プログラミングミス、仕事のミス、生活のミスみたいに分類したい
  2. 検索機能
    • 過去のミスをキーワードで検索できるようにしたい
  3. AIによる改善提案
    • 同じようなミスを繰り返してたら改善案を提案してくれる機能

おわりに

今回はSLMを使ったミスチェック用メモアプリを作ってみました!

LLMほどの高性能は期待できませんが、シンプルなタスクには十分すぎるくらいの性能ですね!
何より、ローカルで動くので個人情報を外部に送らなくていいのが安心です!
仕事のミスとかって機密情報が含まれることもあるので、これは重要なポイントだと思います!
同じミスを繰り返してしまう人(私も含めて)の参考になれば嬉しいです!
皆さんもぜひSLMを使って何か作ってみてください!
きっと新しい発見があると思います!

今回作ったコードはGitHubにも公開しているのでぜひご覧ください!
https://github.com/FrohleinYoshie/miss_check

最後まで読んでいただきありがとうございました!
またどこかの記事でお会いしましょう!

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?