DeepSeek+翻訳モデルで日本語対応した無料ボットを作った(Google Colab)

AI・機械学習

この記事では、Google Colabを使用して、DeepSeek-r1:7bモデルと、翻訳モデルを使って日本語対応の無料ボットを作成する手順を解説します。
本当はサイバーエージェントが公開している14bモデルの日本語対応版を動かしたかったのですが、
GoogleColabの無料版だとメモリが足りなかったので、日本語→英語→DeepSeek→英語回答→日本語回答にすることにしました。

以下記事を参考にさせていただきました。

Google Colab上で簡単に実行できるようにします。

Google Colabのセットアップ

まずはランタイムはGPUにします。

Ollamaのインストール

まず最初に、Ollamaをインストールします。Ollamaは、ローカルでAIモデルを管理および実行するためのツールで、Google ColabでAIモデルを効率的に利用するために必要です。以下のコマンドを実行することで、Ollamaのインストールを行います。

!curl https://ollama.ai/install.sh | sh

このコマンドでは、Ollamaのインストールスクリプトをダウンロードし、実行します。これにより、Ollamaのインストールが完了します。

必要なドライバのインストール

次に、Google ColabでAIモデルを効率よく実行するために必要なCUDAドライバをインストールします。

!echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections
!sudo apt-get update && sudo apt-get install -y cuda-drivers

必要なPythonライブラリのインストール

次に、langchainlangchain_community、およびollamaのPythonパッケージをインストールします。これらは、AIモデルを操作するために必要なライブラリです。

!pip install langchain langchain_community ollama

langchainは、さまざまなAIツールとAPIを簡単に統合できるライブラリです。langchain_communityは、Ollamaなどのサードパーティのモデルをサポートしています。ollamaは、OllamaをPythonから操作するためのライブラリです。

Ollamaのサーバーをバックグラウンドで起動

Ollamaをバックグラウンドで実行するために、以下のコマンドを使用します。これにより、OllamaがAIモデルを提供するサーバーとして機能し、後で使用することができるようになります。

!nohup ollama serve &

nohupを使用することで、Colabが閉じてもOllamaが実行され続けるようになります。これにより、モデルを簡単に使用できるようになります。

翻訳モデルのダウンロード

次に、日本語への翻訳を行うモデルをOllamaからダウンロードします。まずは、7shi/gemma-2-jpn-translateという翻訳モデルをダウンロードします。

!ollama pull 7shi/gemma-2-jpn-translate:2b-instruct-q8_0

次に、DeepSeekのモデルをダウンロードします。このモデルは、質問に対して思考を伴う応答を行うAIです。

!ollama pull deepseek-r1:7b

これで、日本語翻訳とDeepSeekによる推論を行うためのモデルが準備できました。

必要なPythonライブラリのインストール(再確認)

最後に、gradiolangchainをインストールします。これらは、ユーザーインターフェースを作成し、AIモデルと連携させるために必要なライブラリです。

!pip install gradio langchain

gradioは、簡単にインタラクティブなWebインターフェースを作成できるライブラリで、langchainはそのままAIとの連携をスムーズに行います。

これで、セットアップは完了です!

次のステップでは、この環境を使って実際に日本語対応のボットを作成し、ユーザーからの入力に対してAIがどのように応答するかを確認します。

AIボット部分の作成

必要なライブラリのインポート

最初に、必要なライブラリをインポートします。

import gradio as gr
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_community.chat_models import ChatOllama
from langchain_core.output_parsers import StrOutputParser
from langchain.memory import ConversationBufferMemory
import re
  • gradio: ユーザーインターフェースを作成するためのライブラリ。
  • langchain_corelangchain_community: AIモデルとのやりとりを簡素化するためのツール群。
  • re: 正規表現ライブラリで、<think>タグの処理に使用します。

翻訳モデルの作成

def create_translation_chain():
    translate_model = ChatOllama(
        model="7shi/gemma-2-jpn-translate:2b-instruct-q8_0",
        base_url="http://localhost:11434",
        temperature=0.0,
        streaming=True
    )
    return translate_model

この関数では、Ollamaを利用して日本語から英語に翻訳するためのChatOllamaインスタンスを作成します。temperature=0.0は決定論的な応答を生成するための設定です。

推論チェーンの作成

def create_reasoning_chain():
    reasoning_model = ChatOllama(
        model="deepseek-r1:7b",
        base_url="http://localhost:11434",
        temperature=0.0,
        top_p=0.9,
        streaming=True
    )
    memory = ConversationBufferMemory(return_messages=True)
    prompt = ChatPromptTemplate.from_messages([
        ("system", "You are a helpful AI assistant. Please provide a detailed and thoughtful response."),
        MessagesPlaceholder(variable_name="history"),
        ("human", "{input}")
    ])
    chain = prompt | reasoning_model | StrOutputParser()
    return chain, memory

ここでは、DeepSeekの推論用のChatOllamaインスタンスを作成しています。ConversationBufferMemoryを使って、会話の履歴を保存し、過去のメッセージを活用した推論を行います。

翻訳関数の定義

翻訳を行うための関数を定義します。日本語から英語への翻訳と、英語から日本語への翻訳の関数があります。

日本語から英語への翻訳

def translate_to_english(translate_model, text):
    prompt = ChatPromptTemplate.from_messages([
        ("system", "Translate Japanese to English:"),
        ("assistant", "OK"),
        ("human", "{input}")
    ])
    chain = prompt | translate_model | StrOutputParser()
    return chain.stream({"input": text})

英語から日本語への翻訳

def translate_to_japanese(translate_model, text):
    prompt = ChatPromptTemplate.from_messages([
        ("system", "Translate English to Japanese:"),
        ("assistant", "OK"),
        ("human", "{input}")
    ])
    chain = prompt | translate_model | StrOutputParser()
    return chain.stream({"input": text})

これらの関数は、入力されたテキストを翻訳するために、事前にセットアップしたtranslate_modelを使用します。

推論の応答を取得

次に、推論の結果を取得する関数です。

def get_reasoning_response(chain, memory, text):
    memory_variables = memory.load_memory_variables({})
    response_stream = chain.stream({
        "input": text,
        "history": memory_variables["history"]
    })

    full_response = ""
    for chunk in response_stream:
        full_response += chunk
        yield chunk

    memory.save_context({"input": text}, {"output": full_response})

この関数では、英語で生成された質問に対するDeepSeekの応答をリアルタイムで処理します。memory.save_contextを使用して、会話履歴を保存します。

チャット関数の作成

実際にチャットを行うための関数です。この関数では、入力されたテキストを日本語から英語に翻訳し、その後DeepSeekで応答を生成し、最後に英語から日本語に翻訳して出力します。

def chat(input_text):
    translate_model = create_translation_chain()
    reasoning_chain, memory = create_reasoning_chain()

    try:
        output_text = input_text + "\n\n"

        # Step 1: 日本語から英語への翻訳
        output_text += "日本語から英語への翻訳中...\n"
        yield output_text  # 進行状況をリアルタイムで返す
        english_query = ""
        for chunk in translate_to_english(translate_model, input_text):
            english_query += chunk
            output_text += chunk
            yield output_text  # 出力をリアルタイムで更新

        # Step 2: 英語での回答生成
        output_text += "\n\n英語での回答生成中...\n"
        yield output_text  # 進行状況をリアルタイムで返す
        english_response = ""
        for chunk in get_reasoning_response(reasoning_chain, memory, english_query):
            english_response += chunk
            output_text += chunk
            yield output_text  # 出力をリアルタイムで更新

        # Step 3: 英語から日本語への翻訳
        output_text += "\n\n日本語回答...\n"
        yield output_text  # 進行状況をリアルタイムで返す
        last_think_match = re.search(r'</think>', english_response, re.DOTALL)
        if last_think_match:
            english_answer = english_response[last_think_match.end():]
        else:
            english_answer = english_response

        response = ""
        for chunk in translate_to_japanese(translate_model, english_answer):
            response += chunk
            output_text += chunk
            yield output_text  # 出力をリアルタイムで更新

        # Step 4: <think>タグ内の部分を日本語に翻訳
        output_text += "\n\n思考過程...\n"
        yield output_text  # 進行状況をリアルタイムで返す

        # <think>タグ内の部分を抽出し翻訳
        think_text = ""
        if last_think_match:
            think_text = english_response[:last_think_match.end()]

        # <think>タグ内のテキストを日本語に翻訳
        translated_think_text = ""
        for chunk in translate_to_japanese(translate_model, think_text):
            translated_think_text += chunk
            output_text += chunk
            yield output_text  # 出力をリアルタイムで更新

        # ここで翻訳結果を表示するのは1回だけにする
        output_text += f"Thinkタグ内の部分の翻訳:\n{translated_think_text}\n"
        yield output_text  # 最後の翻訳結果もリアルタイムで表示

    except Exception as e:
        output_text += f"エラーが発生しました: {str(e)}"
        yield output_text  # 出力にエラーメッセージを表示

この関数では、以下のステップを実行します:
1. 日本語から英語に翻訳
2. 英語での推論(DeepSeek)
3. 英語から日本語に翻訳
4. thinkタグ内の部分を日本語に翻訳

Gradioインターフェースの作成

最後に、ユーザーとインタラクションするためのインターフェースを作成します。gr.Interfaceを使用して、テキスト入力と出力を設定します。

iface = gr.Interface(
    fn=chat, 
    inputs=gr.Textbox(placeholder="質問を入力してください...", lines=2, interactive=True), 
    outputs="text", 
    live=False,  # チャットが送信されるまで待つ
    title="AIボット DeepSeek",
    allow_flagging="never",  # フラグの使用を禁止(必要に応じて変更)
    theme="huggingface"  # 見た目のテーマを変更(オプション)
)

iface.launch()

これで、ユーザーが質問を入力すると、DeepSeekボットが処理を行い、リアルタイムで応答を返すインターフェースが完成しました。

今回紹介したコードはこちらから確認できます。

タイトルとURLをコピーしました