# FunctionGemma：如何运行和微调

FunctionGemma 是谷歌推出的一款新的 2.7 亿参数模型，专为函数调用和微调而设计。基于 [Gemma 3](/docs/zh/mo-xing/tutorials/gemma-3-how-to-run-and-fine-tune.md) 270M，并专门针对仅文本工具调用训练，它的小体积使其非常适合部署到你自己的手机上。

你可以在 **550MB RAM** （CPU）上运行完整精度模型，并且现在你可以使用 Unsloth 在本地对它进行 **微调** 。感谢 Google DeepMind 与 Unsloth 合作提供首日支持！

<a href="/pages/585492ce9031c7bf11018debd8017628aaf0db18#run-functiongemma" class="button secondary">运行教程</a><a href="/pages/585492ce9031c7bf11018debd8017628aaf0db18#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 需要系统消息或 **开发者消息** 作为 `你是一个可以使用以下函数进行函数调用的模型` 如果你忘记传入，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

下面提供本地桌面指南，或者你也可以查看我们的手机部署指南。

#### 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
./llama.cpp/llama-cli \\
    -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 %}
通过以下方式下载模型（在安装之后 `pip install huggingface_hub hf_transfer` ）。你可以选择 `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
./llama.cpp/llama-cli \\
    --model unsloth/functiongemma-270m-it-GGUF/functiongemma-270m-it-BF16.gguf \\
    --ctx-size 32768 \\
    --n-gpu-layers 99 \\
    --seed 3407 \\
    --prio 2 \\
    --top-k 64 \\
    --top-p 0.95 \\
    --temp 1.0 \\
    --jinja
```

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

## 📱 手机部署

由于其体积很小，你也可以在手机上运行和部署 FunctionGemma。我们与 PyTorch 合作，使用量化感知训练（[QAT](/docs/zh/bo-ke/quantization-aware-training-qat.md)）构建了简化工作流，以恢复 70% 的准确率，然后直接部署到边缘设备上。

* 将 FunctionGemma 本地部署到 **Pixel 8** 和 **iPhone 15 Pro** ，以获得 **约 50 tokens/s 的推理速度**
* 获得隐私优先、即时响应和离线能力
* 使用我们的 [免费 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="/pages/e0e826e45659eab088ef3acd7826998bc36539e9" %}
[Run LLMs on your Phone](/docs/zh/ji-chu/inference-and-deployment/deploy-llms-phone.md)
{% endcontent-ref %}

查看我们的 iOS 和 Android 教程，以便在手机上部署：

<a href="/pages/e0e826e45659eab088ef3acd7826998bc36539e9#ios-deployment" class="button secondary" data-icon="apple">iOS 教程</a><a href="/pages/e0e826e45659eab088ef3acd7826998bc36539e9#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 是一个专门用于函数调用的小型模型。它使用自己独特的聊天模板。在提供工具定义和用户提示时，它会生成结构化输出。然后我们可以解析该输出来执行工具、检索结果，并用这些结果生成最终答案。

| 轮次类型      | 内容                                                                                                                                                                                                                                                                               |
| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **开发者提示** | <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>`实现了一个简化版本，即使用单个思考块（而不是交错推理）。因此，我们的模型交互如下：

| **思考** + **函数调用** | <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="/files/cf168695b2df601ae533306815e08ec2c10f2784" 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星期几是 Wednesday\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="/files/f2102ffdc64d1b67f056c54a1cfed6552d28af61" 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"}
    else:
        return {"temperature": 30, "weather": "rainy"}

def add_numbers(x: float | str, y: float | str):
    """
    将 2 个数字相加

    参数：
        x：第一个数字
        y：第二个数字

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

def multiply_numbers(x: float | str, y: float | str):
    """
    将 2 个数字相乘

    参数：
        x：第一个数字
        y：第二个数字

    返回：
        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 })
    return messages

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)
    return messages
```

{% 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, # [NEW!] 稍微更准确，但会占用 2 倍内存
    load_in_16bit = True, # [NEW!] 启用 16 位 LoRA
    full_finetuning = False, # [NEW!] 我们现在支持完整微调！
    # 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/zh/mo-xing/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.
