| Model | Accuracy | Improvement |
|---|---|---|
| Base FunctionGemma | 75% (6/8 tests) | - |
| Fine-tuned (this model) | 100% (8/8 tests) | +25 percentage points |
song_name (string, required) - Name of the song to playartist (string, optional) - Artist namealbum (string, optional) - Album nameInput: "Play Bohemian Rhapsody by Queen"
Output: call:play_song{song_name:<escape>Bohemian Rhapsody<escape>,artist:<escape>Queen<escape>}action (string, required) - One of: play, pause, skip, next, previous, stop, resumeInput: "Pause the music"
Output: call:playback_control{action:<escape>pause<escape>}query (string, required) - Search querytype (string, optional) - One of: song, artist, album, playlist, genreInput: "Search for rock songs"
Output: call:search_music{query:<escape>rock songs<escape>}name (string, required) - Name of the playlistInput: "Create a playlist called Workout Mix"
Output: call:create_playlist{name:<escape>Workout Mix<escape>}1import torch
2from transformers import AutoTokenizer, AutoModelForCausalLM
3from peft import PeftModel
4
5# Load base model
6base_model = AutoModelForCausalLM.from_pretrained(
7 "google/functiongemma-270m-it",
8 torch_dtype=torch.float32, # Use float32 for CPU, float16 for GPU
9 device_map="cpu", # or "auto" for GPU
10 trust_remote_code=True
11)
12
13# Load tokenizer and fine-tuned adapter
14tokenizer = AutoTokenizer.from_pretrained("google/functiongemma-270m-it")
15model = PeftModel.from_pretrained(base_model, "Jageen/music-4func")
16
17# Optional: Merge for faster inference
18model = model.merge_and_unload()
19
20# Define your functions (same as training)
21FUNCTIONS = [
22 {
23 "type": "function",
24 "function": {
25 "name": "play_song",
26 "description": "Play a specific song by name or artist",
27 "parameters": {
28 "type": "object",
29 "properties": {
30 "song_name": {"type": "string", "description": "Name of the song"},
31 "artist": {"type": "string", "description": "Artist name (optional)"},
32 "album": {"type": "string", "description": "Album name (optional)"}
33 },
34 "required": ["song_name"]
35 }
36 }
37 },
38 {
39 "type": "function",
40 "function": {
41 "name": "playback_control",
42 "description": "Control music playback",
43 "parameters": {
44 "type": "object",
45 "properties": {
46 "action": {
47 "type": "string",
48 "enum": ["play", "pause", "skip", "next", "previous", "stop", "resume"],
49 "description": "Playback action"
50 }
51 },
52 "required": ["action"]
53 }
54 }
55 },
56 {
57 "type": "function",
58 "function": {
59 "name": "search_music",
60 "description": "Search for music",
61 "parameters": {
62 "type": "object",
63 "properties": {
64 "query": {"type": "string", "description": "Search query"},
65 "type": {
66 "type": "string",
67 "enum": ["song", "artist", "album", "playlist", "genre"],
68 "description": "Type of search"
69 }
70 },
71 "required": ["query"]
72 }
73 }
74 },
75 {
76 "type": "function",
77 "function": {
78 "name": "create_playlist",
79 "description": "Create a new playlist",
80 "parameters": {
81 "type": "object",
82 "properties": {
83 "name": {"type": "string", "description": "Playlist name"}
84 },
85 "required": ["name"]
86 }
87 }
88 }
89]
90
91# Test the model
92def predict(user_input):
93 messages = [{"role": "user", "content": user_input}]
94
95 prompt = tokenizer.apply_chat_template(
96 messages,
97 tools=FUNCTIONS,
98 add_generation_prompt=True,
99 tokenize=False
100 )
101
102 inputs = tokenizer(prompt, return_tensors="pt")
103
104 with torch.no_grad():
105 outputs = model.generate(
106 **inputs,
107 max_new_tokens=128,
108 do_sample=False,
109 pad_token_id=tokenizer.eos_token_id
110 )
111
112 response = tokenizer.decode(
113 outputs[0][inputs['input_ids'].shape[1]:],
114 skip_special_tokens=False
115 )
116
117 return response
118
119# Test examples
120print(predict("Play Bohemian Rhapsody"))
121print(predict("Pause the music"))
122print(predict("Search for rock songs"))
123print(predict("Create a playlist called Chill Vibes"))<start_function_call>call:function_name{param1:<escape>value1<escape>,param2:<escape>value2<escape>}<end_function_call>1LoraConfig(
2 r=16, # LoRA rank
3 lora_alpha=32, # LoRA alpha
4 target_modules=[ # All 7 modules (critical!)
5 "q_proj", "k_proj", "v_proj", "o_proj",
6 "gate_proj", "up_proj", "down_proj"
7 ],
8 lora_dropout=0.05,
9 bias="none",
10 task_type="CAUSAL_LM"
11)1messages = [
2 {"role": "user", "content": "Play Bohemian Rhapsody"},
3 {
4 "role": "assistant",
5 "tool_calls": [{
6 "type": "function",
7 "function": {
8 "name": "play_song",
9 "arguments": {"song_name": "Bohemian Rhapsody"} # Dict, not JSON string
10 }
11 }]
12 }
13]| Test | Input | Expected Function | Result |
|---|---|---|---|
| 1 | "Play Bohemian Rhapsody" | play_song | ✅ Pass |
| 2 | "Pause the music" | playback_control | ✅ Pass |
| 3 | "Search for rock songs" | search_music | ✅ Pass |
| 4 | "Create a workout playlist" | create_playlist | ✅ Pass |
| 5 | "Play Stairway to Heaven by Led Zeppelin" | play_song | ✅ Pass |
| 6 | "Skip this song" | playback_control | ✅ Pass |
| 7 | "Find some Beatles songs" | search_music | ✅ Pass |
| 8 | "Make a new playlist called Chill" | create_playlist | ✅ Pass |
| Input | Base Model (75%) | Fine-tuned (100%) |
|---|---|---|
| "Play Bohemian Rhapsody" | ✅ Correct | ✅ Correct |
| "Pause the music" | ✅ Correct | ✅ Correct |
| "Search for rock songs" | ❌ Wrong params | ✅ Correct |
| "Create a workout playlist" | ❌ Hallucinated | ✅ Correct |
| "Play Hotel California by Eagles" | ✅ Correct | ✅ Correct |
| "Skip to next track" | ✅ Correct | ✅ Correct |
| "Find jazz music" | ❌ Wrong function | ✅ Correct |
| "New playlist: Party Mix" | ❌ Invalid format | ✅ Correct |
json.dumps()1// Using HuggingFace Swift SDK
2import Transformers
3
4let model = HuggingFaceModel(
5 modelId: "Jageen/music-4func",
6 baseModel: "google/functiongemma-270m-it"
7)1// Using HuggingFace Android SDK
2import co.huggingface.transformers.*
3
4val model = PeftModel.fromPretrained(
5 baseModel = "google/functiongemma-270m-it",
6 adapter = "Jageen/music-4func"
7)1# Use torch.float16 and device_map="auto" for GPU
2base_model = AutoModelForCausalLM.from_pretrained(
3 "google/functiongemma-270m-it",
4 torch_dtype=torch.float16,
5 device_map="auto"
6)