> For the complete documentation index, see [llms.txt](https://unsloth.ai/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://unsloth.ai/docs/zh/mo-xing/tutorials/functiongemma.md).

# FunctionGemma：如何运行与微调

了解如何在你的设备和手机上本地运行并微调 FunctionGemma。

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

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

<a href="/docs/zh/mo-xing/tutorials/functiongemma.md#run-functiongemma" class="button secondary">运行教程</a><a href="/docs/zh/mo-xing/tutorials/functiongemma.md#fine-tuning-functiongemma" class="button primary">微调 FunctionGemma</a>

* 运行 FunctionGemma GGUF： [unsloth/functiongemma-270m-it-GGUF](https://huggingface.co/unsloth/functiongemma-270m-it-GGUF)

**免费 Notebook：**

* 微调以 **在工具调用前进行推理/思考** 使用我们的 [FunctionGemma Notebook](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/FunctionGemma_\(270M\).ipynb)
* 在 **多轮工具调用** 在一个免费的 [多轮工具调用 Notebook](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 需要 system 或 **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

请参阅下面的本地桌面指南，或者查看我们的手机部署指南。

#### Llama.cpp 教程（GGUF）：

在 llama.cpp 中运行的说明（注意：为了适配大多数设备，我们将使用 4-bit）：

{% 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-bit），因为模型体积很小。

```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 token/秒 的推理速度**
* 获得隐私优先、即时响应和离线能力
* 使用我们的 [免费 Colab Notebook](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-zhi-shi/inference-and-deployment/deploy-llms-phone.md)
{% endcontent-ref %}

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

<a href="/docs/zh/ji-chu-zhi-shi/inference-and-deployment/deploy-llms-phone.md#ios-deployment" class="button secondary" data-icon="apple">iOS 教程</a><a href="/docs/zh/ji-chu-zhi-shi/inference-and-deployment/deploy-llms-phone.md#android-deployment" class="button secondary" data-icon="android">Android 教程</a>

## 🦥 微调 FunctionGemma

Google 指出 **FunctionGemma 旨在被微调** 以适配你的特定函数调用任务，包括多轮使用场景。Unsloth 现已支持对 FunctionGemma 进行微调。我们创建了 2 个微调 Notebook，展示你可以通过以下方式训练模型： **通过 Colab Notebook 免费进行完整微调或 LoRA：**

{% columns %}
{% column %}
[**在调用工具前先思考的微调 Notebook**](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 %}
[**移动端操作微调 Notebook**](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 %}

在 [**在调用工具前先思考的微调 Notebook**](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: "巴黎"</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: "巴黎"</code></p><p><code>}</code></p><p><code>\<end\_function\_call></code></p> |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

## :accordion:用于移动端操作的 FunctionGemma 微调

我们还创建了一个 Notebook，展示如何让 FunctionGemma 执行移动端操作。在 [**移动端操作微调 Notebook**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/FunctionGemma_\(270M\)-Mobile-Actions.ipynb)中，我们也启用了评估，并展示了针对设备端操作进行微调的效果很好，评估损失下降如下：

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

例如，给定一个提示 `请为 2025 年 6 月 6 日星期五下午 2 点设置一个“Team Sync Meeting”的提醒。`

{% 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': '请为 2025 年 6 月 6 日星期五下午 2 点设置一个“Team Sync Meeting”的提醒。',
  'tool_calls': None}]
```

{% endcode %}

我们将模型微调为能够输出：

{% code overflow="wrap" %}

```
<start_of_turn>user
请为 2025 年 6 月 6 日星期五下午 2 点设置一个“Team Sync Meeting”的提醒。<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 的多轮工具调用

我们还创建了一个 Notebook，展示如何让 FunctionGemma 进行多轮工具调用。在 [**多轮工具调用 Notebook**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/FunctionGemma_\(270M\)-Multi-Turn-Tool-Calling.ipynb)中，我们展示了 FunctionGemma 如何在较长的消息变更中调用工具，例如见下：

<figure><img src="https://2657992854-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2F5bewasaWZp4r48LSL0fd%2Fimage.png?alt=media&amp;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"}
    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 个 Notebook：

{% columns %}
{% column %}
[在调用工具前先思考的微调 Notebook](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 %}
[移动端操作微调 Notebook](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 %}
[多轮工具调用 Notebook](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
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

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

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://unsloth.ai/docs/zh/mo-xing/tutorials/functiongemma.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
