# FunctionGemma: 実行とファインチューニングの方法

FunctionGemmaはGoogleが設計した関数呼び出しとファインチューニング向けの新しい270Mパラメータモデルです。ベースは [Gemma 3](https://unsloth.ai/docs/jp/moderu/tutorials/gemma-3-how-to-run-and-fine-tune) 270Mでテキストのみのツール呼び出し向けに特別に訓練されており、その小さなサイズは自分の携帯電話にデプロイするのに最適です。

フル精度モデルを実行できます **550MBのRAM** （CPU）で、そして今あなたは **ファインチューニング** Unslothでローカルに実行できます。日次サポートのためにUnslothと提携してくれたGoogle DeepMindに感謝します！

<a href="#run-functiongemma" class="button secondary">実行チュートリアル</a><a href="#fine-tuning-functiongemma" class="button primary">FunctionGemmaのファインチューニング</a>

* FunctionGemma GGUFを実行するには: [unsloth/functiongemma-270m-it-GGUF](https://huggingface.co/unsloth/functiongemma-270m-it-GGUF)

**無料ノートブック：**

* ファインチューニング先： **ツール呼び出しの前に推論/思考するようにする** を使用して [FunctionGemmaノートブック](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/FunctionGemma_\(270M\).ipynb)
* 行ってください **マルチターンのツール呼び出し** を無料で [マルチターンツール呼び出しノートブック](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/FunctionGemma_\(270M\)-Multi-Turn-Tool-Calling.ipynb)
* ファインチューニング先： **モバイルアクションを有効にする** （カレンダー、タイマー設定）を私たちの [モバイルアクションノートブック](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/FunctionGemma_\(270M\)-Mobile-Actions.ipynb)

### ⚙️ 使用ガイド

Googleは推論のためにこれらの設定を推奨しています：

* `top_k = 64`
* `top_p = 0.95`
* `temperature = 1.0`
* 最大コンテキスト長 = `32,768`&#x20;

チャットテンプレート形式は下記を使用したときに見られます：

{% code overflow="wrap" %}

```python
def get_today_date():
    """ 今日の日付を取得する """
    return {"today_date": "2025年12月18日"}
    
tokenizer.apply_chat_template(
    [
        {"role" : "user", "content" : "今日の日付は何ですか？"},
    ],
    tools = [get_today_date], add_generation_prompt = True, tokenize = False,
)
```

{% endcode %}

#### FunctionGemmaチャットテンプレート形式：

{% hint style="info" %}
FunctionGemmaはシステムまたは **developerメッセージ** を `次の関数で関数呼び出しが可能なモデルです` Unslothのバージョンにはこれが組み込まれているので、渡し忘れても大丈夫です。ですからぜひ [unsloth/functiongemma-270m-it](https://huggingface.co/unsloth/functiongemma-270m-it)
{% endhint %}

{% code overflow="wrap" lineNumbers="true" %}

```
<bos><start_of_turn>developer\n次の関数で関数呼び出しが可能なモデルです<start_function_declaration>declaration:get_today_date{description:<escape>今日の日付を取得します<escape>,parameters:{type:<escape>OBJECT<escape>}}<end_function_declaration><end_of_turn>\n<start_of_turn>user\n今日の日付は何ですか？<end_of_turn>\n<start_of_turn>model\n
```

{% endcode %}

## 🖥️ FunctionGemmaを実行する

下記にローカルデスクトップガイドを示します、またはPhone Deployment Guide（電話へのデプロイガイド）をご覧ください。

#### Llama.cpp チュートリアル（GGUF）：

llama.cppで実行するための手順（ほとんどのデバイスに収めるために4ビットを使用します）：

{% stepper %}
{% step %}
最新の `llama.cpp` を [GitHubで入手してください](https://github.com/ggml-org/llama.cpp)。以下のビルド手順にも従うことができます。を変更してください `-DGGML_CUDA=ON` に `-DGGML_CUDA=OFF` GPUを持っていない場合やCPUで推論したい場合は **Apple Mac / Metalデバイスの場合**、次を設定してください `-DGGML_CUDA=OFF` その後通常通り続行してください — Metalサポートはデフォルトで有効です。

{% code overflow="wrap" %}

```bash
apt-get update
apt-get install pciutils build-essential cmake curl libcurl4-openssl-dev -y
git clone https://github.com/ggml-org/llama.cpp
cmake llama.cpp -B llama.cpp/build \
    -DBUILD_SHARED_LIBS=OFF -DGGML_CUDA=ON -DLLAMA_CURL=ON
cmake --build llama.cpp/build --config Release -j --clean-first --target llama-cli llama-mtmd-cli llama-server llama-gguf-split
cp llama.cpp/build/bin/llama-* llama.cpp
```

{% endcode %}
{% endstep %}

{% step %}
Hugging Faceから直接プルできます。モデルが非常に小さいため、量子化していないフル精度のBF16バリアントを使用します。

```bash
export LLAMA_CACHE="unsloth/GLM-4.7-GGUF"
    -hf unsloth/functiongemma-270m-it-GGUF:BF16 \
    --jinja -ngl 99 --ctx-size 32768 \
    --top-k 64 --top-p 0.95 --temp 1.0
```

{% endstep %}

{% step %}
モデルをダウンロードするには（をインストールした後） `モデルをダウンロードするには（` を選択できます。 `BF16` または他の量子化バージョン（モデルサイズが小さいため4ビット未満に下げることは推奨されません）。

```python
# !pip install huggingface_hub hf_transfer
import os
os.environ["HF_HUB_ENABLE_HF_TRANSFER"] = "1"
from huggingface_hub import snapshot_download
snapshot_download(
    repo_id = "unsloth/functiongemma-270m-it-GGUF",
    local_dir = "unsloth/functiongemma-270m-it-GGUF",
    allow_patterns = ["*BF16*"],
)
```

{% endstep %}

{% step %}
次に会話モードでモデルを実行します：

{% code overflow="wrap" %}

```bash
export LLAMA_CACHE="unsloth/GLM-4.7-GGUF"
    --model unsloth/functiongemma-270m-it-GGUF/functiongemma-270m-it-BF16.gguf \
    --ctx-size 32768 \
    --n-gpu-layers 99 \
    --model unsloth/GLM-4.7-GGUF/UD-Q2_K_XL/GLM-4.7-UD-Q2_K_XL-00001-of-00003.gguf \
    --prio 2 \
    --top-k 64 \
    --temp 1.0 \
    --flash-attn on \
    --jinja
```

{% endcode %}
{% endstep %}
{% endstepper %}

## 📱 電話へのデプロイ

その小ささゆえに、FunctionGemmaは電話上でも実行・デプロイできます。量子化に配慮したトレーニング（[QAT](https://unsloth.ai/docs/jp/burogu/quantization-aware-training-qat))を用いて精度の70%を回復し、それをエッジデバイスに直接デプロイするという合理化されたワークフローをPyTorchと協力して作成しました。

* FunctionGemmaをローカルにデプロイする先： **Pixel 8** と **iPhone 15 Pro** で、 **約50トークン/秒の推論速度を得られます**
* プライバシー重視、即時応答、オフライン機能を手に入れましょう
* 私たちの [無料のColabノートブック](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen3_\(0_6B\)-Phone_Deployment.ipynb) を使ってQwen3 0.6Bをファインチューニングして電話用にエクスポートできます — 単にGemma3に変更し、次の手順に従ってください： [Gemma 3 Executorchドキュメント](https://github.com/pytorch/executorch/tree/main/examples/models/gemma3).

{% content-ref url="../../ji-ben/inference-and-deployment/deploy-llms-phone" %}
[deploy-llms-phone](https://unsloth.ai/docs/jp/ji-ben/inference-and-deployment/deploy-llms-phone)
{% endcontent-ref %}

電話へのデプロイについてはiOSとAndroidのチュートリアルをご覧ください：

<a href="../../../ji-ben/inference-and-deployment/deploy-llms-phone#ios-deployment" class="button secondary" data-icon="apple">iOSチュートリアル</a><a href="../../../ji-ben/inference-and-deployment/deploy-llms-phone#android-deployment" class="button secondary" data-icon="android">Androidチュートリアル</a>

## 🦥 FunctionGemmaのファインチューニング

Googleは次のように述べています： **FunctionGemmaはファインチューニングすることを意図しています** 特定の関数呼び出しタスク、マルチターンの場合を含めて。Unslothは現在FunctionGemmaのファインチューニングをサポートしています。私たちは2つのファインチューニング用ノートブックを作成し、モデルを通じてトレーニングする方法を示しています、 **フルファインチューニングまたはColabノートブック経由のLoRAを無料で：**

{% columns %}
{% column %}
[**ツール呼び出し前に推論するファインチューニングノートブック**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/FunctionGemma_\(270M\).ipynb)

{% embed url="<https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/FunctionGemma_(270M).ipynb>" %}
{% endcolumn %}

{% column %}
[**モバイルアクションファインチューニングノートブック**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/FunctionGemma_\(270M\)-Mobile-Actions.ipynb)

{% embed url="<https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/FunctionGemma_(270M)-Mobile-Actions.ipynb>" %}
{% endcolumn %}
{% endcolumns %}

の中で、 [**ツール呼び出し前に推論するファインチューニングノートブック**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/FunctionGemma_\(270M\).ipynb)私たちは **ファンクション呼び出しの前に「考える/推論する」ようにファインチューニングします**。チェイン・オブ・ソート（思考連鎖）による推論はツール利用能力を向上させるためにますます重要になっています。

FunctionGemmaは関数呼び出しに特化した小さなモデルです。独自のチャットテンプレートを利用します。ツール定義とユーザープロンプトが提供されると、構造化された出力を生成します。次にこの出力を解析してツールを実行し、結果を取得して最終回答の生成に使用できます。

| ターンタイプ             | 内容                                                                                                                                                                                                                                                                                   |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Developerプロンプト** | <p><code>\<start\_of\_turn>developer</code></p><p><code>次の関数で関数呼び出しが可能です：</code></p>                                                                                                                                                                                                 |
| **関数宣言**           | <p><code>\<start\_function\_declaration>declaration:get\_weather{</code></p><p><code>description: "都市の天気を取得する",</code></p><p><code>parameters: { city: STRING }</code></p><p><code>}</code></p><p><code>\<end\_function\_declaration></code></p><p><code>\<end\_of\_turn></code></p> |
| **ユーザーターン**        | <p><code>\<start\_of\_turn>user</code></p><p><code>パリの天気はどうですか？</code></p><p><code>\<end\_of\_turn></code></p>                                                                                                                                                                       |
| **関数呼び出し**         | <p><code>\<start\_of\_turn>model</code></p><p><code>\<start\_function\_call>call:get\_weather{</code></p><p><code>city: "paris"</code></p><p><code>}</code></p><p><code>\<end\_function\_call></code></p>                                                                            |
| **関数レスポンス**        | <p><code>\<start\_function\_response>response:get\_weather{temperature:26}</code></p><p><code>\<end\_function\_response></code></p>                                                                                                                                                  |
| **アシスタントの締めくくり**   | <p><code>パリの天気は摂氏26度です。</code></p><p><code>\<end\_of\_turn></code></p>                                                                                                                                                                                                               |

ここでは、インタリーブされた推論ではなく単一の思考ブロックを使用する単純化されたバージョンを実装します（したがって）、 `<think></think>`その結果、私たちのモデルとのやり取りは次のようになります：

| **Thinking** + **関数呼び出し** | <p><code>\<start\_of\_turn>model</code></p><p><mark style="color:青;"><strong><code>\<think></code></strong></mark></p><p><mark style="color:青;"><strong><code>ユーザーはパリの天気を求めています。私はget\_weatherツールを持っています。city引数で呼び出すべきです。</code></strong></mark></p><p><mark style="color:青;"><strong><code>\</think></code></strong></mark></p><p><code>\<start\_function\_call>call:get\_weather{</code></p><p><code>city: "paris"</code></p><p><code>}</code></p><p><code>\<end\_function\_call></code></p> |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

## :accordion:モバイルアクション向けのFunctionGemmaのファインチューニング

また、FunctionGemmaにモバイルアクションを実行させる方法を示すノートブックも作成しました。 [**モバイルアクションファインチューニングノートブック**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/FunctionGemma_\(270M\)-Mobile-Actions.ipynb)その中で、評価も有効にし、デバイス上でのアクション向けにファインチューニングすることがうまく機能することを示しており、評価損失が下がる様子が見られます：

<figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FkRax7Sl7fN7fN3GoFgiG%2Fimage.png?alt=media&#x26;token=e9b648f9-27ae-408b-aa0d-0baf77e5403d" alt="" width="375"><figcaption></figcaption></figure>

例えばプロンプトが与えられた場合 `「Team Sync Meeting」というリマインダーを2025年6月6日（金）午後2時に設定してください。`

{% code overflow="wrap" %}

```python
[{'role': 'developer',
  'content': '現在の日付と時刻はYYYY-MM-DDTHH:MM:SS形式で与えられます: 2025-06-04T15:29:23\n曜日は水曜日です\n次の関数で関数呼び出しが可能なモデルです\n',
  'tool_calls': None},
 {'role': 'user',
  'content': '「Team Sync Meeting」というリマインダーを2025年6月6日（金）午後2時に設定してください。',
  'tool_calls': None}]
```

{% endcode %}

モデルを次のような出力を出せるようにファインチューニングしました：

{% code overflow="wrap" %}

```
<start_of_turn>user
「Team Sync Meeting」というリマインダーを2025年6月6日（金）午後2時に設定してください。<end_of_turn>
<start_of_turn>model
<start_function_call>call:create_calendar_event{body:None,datetime:2025-06-06 14:00:00,email:None,first_name:None,last_name:None,phone_number:None,query:None,subject:None,title:<escape>Team Sync Meeting<escape>,to:None}<end_function_call><start_function_response>
```

{% endcode %}

## :man\_running:FunctionGemmaによるマルチターンツール呼び出し

また、FunctionGemmaがマルチターンのツール呼び出しを行える方法を示すノートブックも作成しました。 [**マルチターンツール呼び出しノートブック**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/FunctionGemma_\(270M\)-Multi-Turn-Tool-Calling.ipynb)その中で、FunctionGemmaが長いメッセージ変更の中でツールを呼び出せることを示しています。例えば以下を参照してください：

<figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2F5bewasaWZp4r48LSL0fd%2Fimage.png?alt=media&#x26;token=6aab6fd4-1560-4a46-ac41-305764019440" alt=""><figcaption></figcaption></figure>

まず以下のようにツールを指定する必要があります：

{% code expandable="true" %}

```python
def get_today_date():
    """
    今日の日付を取得します

    返り値：
        today_date: 日付（例：2025年12月18日の形式）
    """
    from datetime import datetime
    today_date = datetime.today().strftime("%d %B %Y")
    return {"today_date": today_date}

def get_current_weather(location: str, unit: str = "celsius"):
    """
    指定した場所の現在の天気を取得します。

    引数：
        location: 都市と州、例："San Francisco, CA, USA"や"Sydney, Australia"
        unit: 温度を返す単位。（選択肢: ["celsius", "fahrenheit"])

    返り値：
        temperature: 指定された場所の現在の気温
        weather: 指定された場所の現在の天気
    """
    if "San Francisco" in location.title():
        return {"temperature": 15, "weather": "sunny"}
    elif "Sydney" in location.title():
        return {"temperature": 25, "weather": "cloudy"}
    out = MAP_FN[fx](**json.loads(args))
        return {"temperature": 30, "weather": "rainy"}

def add_numbers(x: float | str, y: float | str):
    """
    2つの数を加算します

    引数：
        x: 最初の数
        y: 2番目の数

    返り値：
        result: x + y
    """
    return {"result" : float(x) + float(y)}

def multiply_numbers(x: float | str, y: float | str):
    """
    2つの数を乗算します

    引数：
        x: 最初の数
        y: 2番目の数

    返り値：
        result: x * y
    """
    return {"result" : float(x) * float(y)}
```

{% endcode %}

次にすべてのツールのマッピングを作成します：

```python
FUNCTION_MAPPING = {
    "get_today_date" : get_today_date,
    "get_current_weather" : get_current_weather,
    "add_numbers": add_numbers,
    "multiply_numbers": multiply_numbers,
}
TOOLS = list(FUNCTION_MAPPING.values())
```

ツール呼び出しと解析のコードも必要です：

{% code expandable="true" %}

```python
#@title FunctionGemma解析コード（拡張可能）
import re
def extract_tool_calls(text):
    def cast(v):
        try: return int(v)
        except:
            try: return float(v)
            except: return {'true': True, 'false': False}.get(v.lower(), v.strip("'\""))

    return [{
        "name": name,
        "arguments": {
            k: cast((v1 or v2).strip())
            for k, v1, v2 in re.findall(r"(\w+):(?:<escape>(.*?)<escape>|([^,}]*))", args)
        }
    } for name, args in re.findall(r"<start_function_call>call:(\w+)\{(.*?)\}<end_function_call>", text, re.DOTALL)]

def process_tool_calls(output, messages):
    calls = extract_tool_calls(output)
    if not calls: return messages
    messages.append({
        "role": "assistant",
        "tool_calls": [{"type": "function", "function": call} for call in calls]
    })
    results = [
        {"name": c['name'], "response": FUNCTION_MAPPING[c['name']](**c['arguments'])}
        for c in calls
    ]
    messages.append({ "role": "tool", "content": results })
    else:

def _do_inference(model, messages, max_new_tokens = 128):
    inputs = tokenizer.apply_chat_template(
        messages, tools = TOOLS, add_generation_prompt = True, return_dict = True, return_tensors = "pt",
    )
    output = tokenizer.decode(inputs["input_ids"][0], skip_special_tokens = False)

    out = model.generate(**inputs.to(model.device), max_new_tokens = max_new_tokens,
                         top_p = 0.95, top_k = 64, temperature = 1.0,)
    generated_tokens = out[0][len(inputs["input_ids"][0]):]
    return tokenizer.decode(generated_tokens, skip_special_tokens = True)
    
def do_inference(model, messages, print_assistant = True, max_new_tokens = 128):
    output = _do_inference(model, messages, max_new_tokens = max_new_tokens)
    messages = process_tool_calls(output, messages)
    if messages[-1]["role"] == "tool":
        output = _do_inference(model, messages, max_new_tokens = max_new_tokens)
    messages.append({"role": "assistant", "content": output})
    if print_assistant: print(output)
    else:
```

{% endcode %}

そして今、モデルを呼び出すことができます！

```python
from unsloth import FastLanguageModel
import torch
max_seq_length = 4096 # 任意のシーケンス長を選べます！
model, tokenizer = FastLanguageModel.from_pretrained(
    model_name = "unsloth/functiongemma-270m-it",
    max_seq_length = max_seq_length, # 長いコンテキストのために任意の値を選んでください！
    load_in_4bit = False,  # メモリ削減のための4ビット量子化
    load_in_8bit = False, # [新機能！] 若干精度が高く、2倍のメモリを使用
    load_in_16bit = True, # [新機能！] 16ビットLoRAを有効にする
    full_finetuning = False, # [新機能！] フルファインチューニングが利用可能です！
    # token = "hf_...", # ゲート付きモデルを使用する場合はこれを使う
)

messages = []
messages.append({"role": "user", "content": "今日の日付は何ですか？"})
messages = do_inference(model, messages, max_new_tokens = 128)
```

私たちがFunctionGemmaのために作成した3つのノートブックを試してみてください：

{% columns %}
{% column %}
[ツール呼び出し前に推論するファインチューニングノートブック](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/FunctionGemma_\(270M\).ipynb)

{% embed url="<https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/FunctionGemma_(270M).ipynb>" %}
{% endcolumn %}

{% column %}
[モバイルアクションファインチューニングノートブック](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/FunctionGemma_\(270M\)-Mobile-Actions.ipynb)

{% embed url="<https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/FunctionGemma_(270M)-Mobile-Actions.ipynb>" %}
{% endcolumn %}

{% column %}
[マルチターンツール呼び出しノートブック](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/FunctionGemma_\(270M\)-Multi-Turn-Tool-Calling.ipynb)

{% embed url="<https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/FunctionGemma_(270M)-Multi-Turn-Tool-Calling.ipynb>" %}
{% endcolumn %}
{% endcolumns %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://unsloth.ai/docs/jp/moderu/tutorials/functiongemma.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
