# FunctionGemma : comment l'exécuter et le fine-tuner

FunctionGemma est un nouveau modèle de 270M paramètres par Google conçu pour l'appel de fonctions et l'affinage. [Gemma 3](https://unsloth.ai/docs/fr/modeles/tutorials/gemma-3-how-to-run-and-fine-tune) 270M et entraîné spécifiquement pour l'appel d'outils textuels uniquement, sa petite taille le rend idéal à déployer sur votre propre téléphone.

Vous pouvez exécuter le modèle en précision complète sur **550 Mo de RAM** (CPU) et vous pouvez maintenant **l'affiner** l'exécuter localement avec Unsloth. Merci à Google DeepMind pour avoir collaboré avec Unsloth pour un support dès le jour zéro !

<a href="#run-functiongemma" class="button secondary">Tutoriel d’exécution</a><a href="#fine-tuning-functiongemma" class="button primary">Affinage de FunctionGemma</a>

* FunctionGemma GGUF à exécuter : [unsloth/functiongemma-270m-it-GGUF](https://huggingface.co/unsloth/functiongemma-270m-it-GGUF)

**Notebooks gratuits :**

* Affiner pour **raisonner/réfléchir avant les appels d'outils** en utilisant notre [notebook FunctionGemma](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/FunctionGemma_\(270M\).ipynb)
* Faire **appel d'outils multi-tours** dans un [Notebook d'appel d'outils Multi Turn gratuit](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/FunctionGemma_\(270M\)-Multi-Turn-Tool-Calling.ipynb)
* Affiner pour **activer les actions mobiles** (calendrier, définir une minuterie) dans notre [notebook Actions Mobiles](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/FunctionGemma_\(270M\)-Mobile-Actions.ipynb)

### ⚙️ Guide d'utilisation

Google recommande ces paramètres pour l'inférence :

* `top_k = 64`
* `top_p = 0.95`
* `température = 1.0`
* longueur maximale du contexte = `32,768`&#x20;

Le format du modèle de chat est trouvé lorsque nous utilisons ce qui suit :

{% code overflow="wrap" %}

```python
def get_today_date():
    """ Récupère la date d'aujourd'hui """
    return {"today_date": "18 décembre 2025"}
    
tokenizer.apply_chat_template(
    [
        {"role" : "user", "content" : "quelle est la date d'aujourd'hui ?"},
    ],
    tools = [get_today_date], add_generation_prompt = True, tokenize = False,
)
```

{% endcode %}

#### Format du template de chat FunctionGemma :

{% hint style="info" %}
FunctionGemma requiert le message système ou **message développeur** comme `Vous êtes un modèle qui peut appeler des fonctions avec les fonctions suivantes` Les versions Unsloth ont ceci préconstruit si vous oubliez d'en fournir un, donc veuillez utiliser [unsloth/functiongemma-270m-it](https://huggingface.co/unsloth/functiongemma-270m-it)
{% endhint %}

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

```
<bos><start_of_turn>developer\nVous êtes un modèle qui peut appeler des fonctions avec les fonctions suivantes<start_function_declaration>declaration:get_today_date{description:<escape>Récupère la date d'aujourd'hui<escape>,parameters:{type:<escape>OBJECT<escape>}}<end_function_declaration><end_of_turn>\n<start_of_turn>user\nquelle est la date d'aujourd'hui ?<end_of_turn>\n<start_of_turn>model\n
```

{% endcode %}

## 🖥️ Exécuter FunctionGemma

Voir ci-dessous pour un guide local sur bureau ou vous pouvez consulter notre Guide de déploiement sur téléphone.

#### Tutoriel Llama.cpp (GGUF) :

Instructions pour exécuter dans llama.cpp (notez que nous utiliserons du 4 bits pour tenir sur la plupart des dispositifs) :

{% stepper %}
{% step %}
Obtenez la dernière `llama.cpp` sur [GitHub ici](https://github.com/ggml-org/llama.cpp). Vous pouvez aussi suivre les instructions de compilation ci-dessous. Changez `-DGGML_CUDA=ON` en `-DGGML_CUDA=OFF` si vous n'avez pas de GPU ou si vous voulez simplement de l'inférence CPU. **Pour les appareils Apple Mac / Metal**, définissez `-DGGML_CUDA=OFF` puis continuez comme d'habitude - le support Metal est activé par défaut.

{% 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 %}
Vous pouvez récupérer directement depuis Hugging Face. Parce que le modèle est si petit, nous utiliserons la variante BF16 en pleine précision non quantifiée.

```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 %}
Téléchargez le modèle via (après avoir installé `pip install huggingface_hub hf_transfer` ). Vous pouvez choisir `BF16` ou d'autres versions quantifiées (bien qu'il ne soit pas recommandé de descendre en dessous de 4 bits) en raison de la petite taille du modèle.

```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 %}
Ensuite, exécutez le modèle en mode conversation :

{% 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 %}

## 📱 Déploiement sur téléphone

Vous pouvez également exécuter et déployer FunctionGemma sur votre téléphone grâce à sa petite taille. Nous avons collaboré avec PyTorch pour créer un flux de travail simplifié utilisant l'entraînement sensible à la quantification ([QAT](https://unsloth.ai/docs/fr/blog/quantization-aware-training-qat)) pour récupérer 70 % de précision puis les déployer directement sur des appareils en périphérie.

* Déployer FunctionGemma localement sur **Pixel 8** et **iPhone 15 Pro** pour obtenir **des vitesses d'inférence d'environ \~50 tokens/s**
* Obtenez la confidentialité en priorité, des réponses instantanées et des capacités hors ligne
* Utilisez notre [notebook Colab gratuit](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen3_\(0_6B\)-Phone_Deployment.ipynb) pour affiner Qwen3 0.6B et l'exporter pour le déploiement sur téléphone - changez-le simplement en Gemma3, et suivez la [documentation Gemma 3 Executorch](https://github.com/pytorch/executorch/tree/main/examples/models/gemma3).

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

Consultez nos tutoriels iOS et Android pour le déploiement sur votre téléphone :

<a href="../../../bases/inference-and-deployment/deploy-llms-phone#ios-deployment" class="button secondary" data-icon="apple">Tutoriel iOS</a><a href="../../../bases/inference-and-deployment/deploy-llms-phone#android-deployment" class="button secondary" data-icon="android">Tutoriel Android</a>

## 🦥 Affinage de FunctionGemma

Google a noté que **FunctionGemma est destiné à être affiné** pour votre tâche spécifique d'appel de fonctions, y compris les cas d'utilisation multi-tours. Unsloth prend désormais en charge l'affinage de FunctionGemma. Nous avons créé 2 notebooks d'affinage, qui montrent comment vous pouvez entraîner le modèle via **affinage complet ou LoRA gratuitement via un Notebook Colab :**

{% columns %}
{% column %}
[**Notebook d'affinage Reason before Tool Calling**](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 d'affinage Mobile Actions**](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 %}

Dans le [**Notebook d'affinage Reason before Tool Calling**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/FunctionGemma_\(270M\).ipynb), nous allons **l'affiner pour "penser/raisonner" avant l'appel de fonction**. Le raisonnement de type chaîne de pensée devient de plus en plus important pour améliorer les capacités d'utilisation d'outils.

FunctionGemma est un petit modèle spécialisé pour l'appel de fonctions. Il utilise son propre template de chat distinct. Lorsqu'on lui fournit des définitions d'outils et une invite utilisateur, il génère une sortie structurée. Nous pouvons ensuite analyser cette sortie pour exécuter l'outil, récupérer les résultats et les utiliser pour générer la réponse finale.

| Type de tour                | Contenu                                                                                                                                                                                                                                                                                                     |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Invite développeur**      | <p><code>\<start\_of\_turn>developer</code></p><p><code>Vous pouvez appeler des fonctions avec les fonctions suivantes :</code></p>                                                                                                                                                                         |
| **Déclaration de fonction** | <p><code>\<start\_function\_declaration>declaration:get\_weather{</code></p><p><code>description : "Obtenir la météo pour une ville",</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> |
| **Tour de l'utilisateur**   | <p><code>\<start\_of\_turn>user</code></p><p><code>Quel temps fait-il à Paris ?</code></p><p><code>\<end\_of\_turn></code></p>                                                                                                                                                                              |
| **Appel de fonction**       | <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>                                                                                                   |
| **Réponse de la fonction**  | <p><code>\<start\_function\_response>response:get\_weather{temperature:26}</code></p><p><code>\<end\_function\_response></code></p>                                                                                                                                                                         |
| **Clôture de l'assistant**  | <p><code>Le temps à Paris est de 26 degrés Celsius.</code></p><p><code>\<end\_of\_turn></code></p>                                                                                                                                                                                                          |

Ici, nous implémentons une version simplifiée utilisant un seul bloc de réflexion (plutôt que du raisonnement entrelacé) via `<think></think>`. Par conséquent, notre interaction avec le modèle ressemble à ceci :

| **Thinking** + **Appel de fonction** | <p><code>\<start\_of\_turn>model</code></p><p><mark style="color:bleu;"><strong><code>\<think></code></strong></mark></p><p><mark style="color:bleu;"><strong><code>L'utilisateur veut la météo pour Paris. J'ai l'outil get\_weather. Je devrais l'appeler avec l'argument city.</code></strong></mark></p><p><mark style="color:bleu;"><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:Affinage de FunctionGemma pour les Actions Mobiles

Nous avons également créé un notebook pour montrer comment faire effectuer des actions mobiles par FunctionGemma. Dans le [**Notebook d'affinage Mobile Actions**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/FunctionGemma_\(270M\)-Mobile-Actions.ipynb), nous avons également activé l'évaluation, et montrons comment l'affinage pour des actions sur appareil fonctionne bien, comme le montre la perte d'évaluation qui diminue :

<figure><img src="https://550366147-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>

Par exemple, donnée une invite `Veuillez définir un rappel pour une "Réunion d'équipe" ce vendredi 6 juin 2025, à 14 h.`

{% code overflow="wrap" %}

```python
[{'role': 'developer',
  'content': 'Date et heure actuelles données au format YYYY-MM-DDTHH:MM:SS : 2025-06-04T15:29:23\nLe jour de la semaine est mercredi\nVous êtes un modèle qui peut appeler des fonctions avec les fonctions suivantes\n',
  'tool_calls': None},
 {'role': 'user',
  'content': 'Veuillez définir un rappel pour une "Réunion d\'équipe" ce vendredi 6 juin 2025, à 14 h.',
  'tool_calls': None}]
```

{% endcode %}

Nous avons affiné le modèle pour qu'il puisse produire :

{% code overflow="wrap" %}

```
<start_of_turn>user
Veuillez définir un rappel pour une "Réunion d'équipe" ce vendredi 6 juin 2025, à 14 h.<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:Appels d'outils Multi Turn avec FunctionGemma

Nous avons aussi créé un notebook pour montrer comment faire effectuer des appels d'outils multi-tours par FunctionGemma. Dans le [**Notebook d'appel d'outils Multi Turn gratuit**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/FunctionGemma_\(270M\)-Multi-Turn-Tool-Calling.ipynb), nous montrons comment FunctionGemma est capable d'appeler des outils dans un long changement de message, par exemple voir ci-dessous :

<figure><img src="https://550366147-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>

Vous devez d'abord spécifier vos outils comme ci-dessous :

{% code expandable="true" %}

```python
def get_today_date():
    """
    Récupère la date d'aujourd'hui

    Retourne :
        today_date : Date du jour au format 18 décembre 2025
    """
    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"):
    """
    Récupère la météo actuelle pour un emplacement donné.

    Args :
        location : La ville et l'état, par ex. "San Francisco, CA, USA" ou "Sydney, Australia"
        unit : L'unité pour retourner la température. (choix : ["celsius", "fahrenheit"])

    Retourne :
        temperature : La température actuelle à l'emplacement donné
        weather : La météo actuelle à l'emplacement donné
    """
    if "San Francisco" in location.title():
        return {"temperature": 15, "weather": "ensoleillé"}
    elif "Sydney" in location.title():
        return {"temperature": 25, "weather": "nuageux"}
    else:
        return {"temperature": 30, "weather": "pluvieux"}

def add_numbers(x: float | str, y: float | str):
    """
    Additionne 2 nombres

    Args :
        x : Premier nombre
        y : Deuxième nombre

    Retourne :
        resultat : x + y
    """
    return {"result" : float(x) + float(y)}

def multiply_numbers(x: float | str, y: float | str):
    """
    Multiplie 2 nombres

    Args :
        x : Premier nombre
        y : Deuxième nombre

    Retourne :
        resultat : x * y
    """
    return {"result" : float(x) * float(y)}
```

{% endcode %}

Nous créons ensuite un mapping pour tous les outils :

```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())
```

Nous avons également besoin d'un peu de code d'invocation et d'analyse d'outils :

{% code expandable="true" %}

```python
#@title Code d'analyse FunctionGemma (extensible)
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 %}

Et maintenant nous pouvons appeler le modèle !

```python
from unsloth import FastLanguageModel
import torch
max_seq_length = 4096 # Vous pouvez choisir n'importe quelle longueur de séquence !
model, tokenizer = FastLanguageModel.from_pretrained(
    model_name = "unsloth/functiongemma-270m-it",
    max_seq_length = max_seq_length, # Choisissez n'importe quelle valeur pour un long contexte !
    load_in_4bit = False,  # Quantification 4 bits pour réduire la mémoire
    load_in_8bit = False, # [NOUVEAU !] Un peu plus précis, utilise 2x la mémoire
    load_in_16bit = True, # [NOUVEAU !] Active LoRA 16 bits
    full_finetuning = False, # [NOUVEAU !] Nous avons maintenant l'affinage complet !
    # token = "hf_...", # en utiliser un si vous utilisez des modèles restreints
)

messages = []
messages.append({"role": "user", "content": "Quelle est la date d'aujourd'hui ?"})
messages = do_inference(model, messages, max_new_tokens = 128)
```

Essayez les 3 notebooks que nous avons créés pour FunctionGemma :

{% columns %}
{% column %}
[Notebook d'affinage Reason before Tool Calling](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 d'affinage Mobile Actions](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 d'appel d'outils Multi Turn gratuit](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/fr/modeles/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.
