DiTy commited on
Commit
94e5830
1 Parent(s): b9ebbe9

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +412 -3
README.md CHANGED
@@ -1,3 +1,412 @@
1
- ---
2
- license: apache-2.0
3
- ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ base_model: DiTy/gemma-2-9b-it-russian-function-calling-GGUF
3
+ datasets:
4
+ - DiTy/function-calling-trl
5
+ language:
6
+ - ru
7
+ library_name: transformers
8
+ license: apache-2.0
9
+ pipeline_tag: text-generation
10
+ tags:
11
+ - conversational
12
+ - gemma2
13
+ - function-calling
14
+ - trl
15
+ ---
16
+ # DiTy/gemma-2-9b-it-russian-function-calling-DPO-GGUF
17
+
18
+ This model is a aligned version of [DiTy/gemma-2-9b-it-russian-function-calling-GGUF](https://huggingface.co/DiTy/gemma-2-9b-it-russian-function-calling-GGUF) for more **Stricted Function Calling** task.
19
+ Which means that the model avoids answering user questions that are not related to the described functions.
20
+
21
+ Example of behavior of the base and alignment model:
22
+
23
+ | PROMPT | | File Size | Description |
24
+ | -------- | ---------- | --------- | ----------- |
25
+
26
+ The model has been trained using non-synthetic preference data, fully annotated by humans only, on the Russian version of the <ins>*DiTy/function-calling-trl*</ins> dataset.
27
+ <!-- Provide a quick summary of what the model is/does. -->
28
+
29
+ In addition to **safetensors**, the model is available in **GGUF** formats (in this case, you need to download only a single file (*[how to inference GGUF model](https://github.com/abetlen/llama-cpp-python?tab=readme-ov-file#high-level-api)*)):
30
+
31
+ | Filename | Quant type | File Size | Description |
32
+ | -------- | ---------- | --------- | ----------- |
33
+ | [gemma-2-9B-it-russian-function-calling-F16.gguf](https://huggingface.co/DiTy/gemma-2-9b-it-russian-function-calling-GGUF/blob/main/gemma-2-9B-it-russian-function-calling-F16.gguf) | F16 | 18.5GB | Base model with float16 |
34
+ | [gemma-2-9B-it-russian-function-calling-Q8_0.gguf](https://huggingface.co/DiTy/gemma-2-9b-it-russian-function-calling-GGUF/blob/main/gemma-2-9B-it-russian-function-calling-Q8_0.gguf) | Q8_0 | 9.83GB | Extremely high quality, generally unneeded but max available quant. |
35
+ | [gemma-2-9B-it-russian-function-calling-Q6_K.gguf](https://huggingface.co/DiTy/gemma-2-9b-it-russian-function-calling-GGUF/blob/main/gemma-2-9B-it-russian-function-calling-Q6_K.gguf) | Q6_K | 7.59GB | Very high quality, near perfect, *recommended*. |
36
+ | [gemma-2-9B-it-russian-function-calling-Q5_K_M.gguf](https://huggingface.co/DiTy/gemma-2-9b-it-russian-function-calling-GGUF/blob/main/gemma-2-9B-it-russian-function-calling-Q5_K_M.gguf) | Q5_K_M | 6.65GB | High quality, very usable. |
37
+ | [gemma-2-9B-it-russian-function-calling-Q5_K_S.gguf](https://huggingface.co/DiTy/gemma-2-9b-it-russian-function-calling-GGUF/blob/main/gemma-2-9B-it-russian-function-calling-Q5_K_S.gguf) | Q5_K_S | 6.48GB | High quality, very usable. |
38
+
39
+
40
+ ## Model card разделы
41
+
42
+ * [Как подготовить ваши функции (tools) для *Function Calling*](#prepare_func_call)
43
+ * [Просто используйте chat template для генерации](#just_chat_template)
44
+ * [Prompt структура и ожидаемый контент](#roles)
45
+ * [Оценка моделей под вызов функций](#eval)
46
+
47
+ ## Использование (HuggingFace Transformers)
48
+
49
+ Ниже представлены некоторые фрагменты кода о том, как быстро приступить к запуску модели. Сначала установите библиотеку Transformers с помощью:
50
+ ```bash
51
+ pip install -U transformers
52
+ ```
53
+
54
+ ### <a name="prepare_func_call"></a>Как подготовить ваши функции (tools) для *Function Calling*
55
+
56
+ Вы должны написать функции (инструменты), используемые моделью, в *коде на Python* и обязательно добавить *Python docstrings*, как в примере ниже:
57
+ ```python
58
+ def get_weather(city: str):
59
+ """
60
+ Функция, которая возвращает погоду в заданном городе.
61
+
62
+ Args:
63
+ city: Город, для которого надо узнать погоду.
64
+ """
65
+ import random
66
+
67
+ return "sunny" if random.random() > 0.5 else "rainy"
68
+ def get_sunrise_sunset_times(city: str):
69
+ """
70
+ Функция, которая возвращает время восхода и заката для заданного города для текущей даты (дата от пользователя не требуется), в формате списка: [sunrise_time, sunset_time].
71
+
72
+ Args:
73
+ city: Город, в котором можно узнать время восхода и захода солнца.
74
+ """
75
+ return ["6:00", "18:00"]
76
+ ```
77
+
78
+ ### <a name="just_chat_template"></a>Просто используйте chat template для генерации
79
+
80
+ Далее вам нужно загрузить модель и токенизатор:
81
+ ```python
82
+ import torch
83
+ from transformers import AutoTokenizer, AutoModelForCausalLM
84
+ model = AutoModelForCausalLM.from_pretrained(
85
+ "DiTy/gemma-2-9b-it-russian-function-calling-GGUF",
86
+ device_map="auto",
87
+ torch_dtype=torch.bfloat16, # use float16 or float32 if bfloat16 is not available to you.
88
+ cache_dir=PATH_TO_MODEL_DIR, # optional
89
+ )
90
+ tokenizer = AutoTokenizer.from_pretrained(
91
+ "DiTy/gemma-2-9b-it-russian-function-calling-GGUF",
92
+ cache_dir=PATH_TO_MODEL_DIR, # optional
93
+ )
94
+ ```
95
+
96
+ Чтобы получить результат генерации, просто используйте `apply_chat_template`. Чтобы учесть наши написанные функции (инструменты),
97
+ нам нужно передать их в виде списка через атрибут `tools`, а также использовать `add_prompt_generation=True`.
98
+ ```python
99
+ history_messages = [
100
+ {"role": "system", "content": "Ты - полезный помощник, имеющий доступ к следующим функциям. Используйте их при необходимости - "},
101
+ {"role": "user", "content": "Привет, не мог бы ты сказать мне, во сколько в Краснодаре восходит солнце?"}
102
+ ]
103
+ inputs = tokenizer.apply_chat_template(
104
+ history_messages,
105
+ tokenize=False,
106
+ add_generation_prompt=True, # adding prompt for generation
107
+ tools=[get_weather, get_sunrise_sunset_times], # our functions (tools)
108
+ )
109
+ print(inputs)
110
+ ```
111
+
112
+ Тогда наш `inputs` будет выглядеть следующим образом:
113
+ ```
114
+ <bos><start_of_turn>user
115
+ Ты - полезный помощник, имеющий доступ к следующим функциям. Используйте их при необходимости - {
116
+ "name": "get_weather",
117
+ "description": "Функция, которая возвращает погоду в заданном городе.",
118
+ "parameters": {
119
+ "type": "object",
120
+ "properties": {
121
+ "city": {
122
+ "type": "string",
123
+ "description": "Город, для которого надо узнать погоду."
124
+ }
125
+ },
126
+ "required": [
127
+ "city"
128
+ ]
129
+ }
130
+ },
131
+ {
132
+ "name": "get_sunrise_sunset_times",
133
+ "description": "Функция, которая возвращает время восхода и заката для заданного города для текущей даты (дата от пользователя не требуется), в формате списка: [sunrise_time, sunset_time].",
134
+ "parameters": {
135
+ "type": "object",
136
+ "properties": {
137
+ "city": {
138
+ "type": "string",
139
+ "description": "Город, в котором можно узнать время восхода и захода солнца."
140
+ }
141
+ },
142
+ "required": [
143
+ "city"
144
+ ]
145
+ }
146
+ }
147
+ Привет, не мог бы ты сказать мне, во сколько в Краснодаре восходит солнце?<end_of_turn>
148
+ <start_of_turn>model
149
+ ```
150
+
151
+ Теперь мы можем сгенерировать ответ модели.
152
+ Будьте осторожны, потому что после `apply_chat_template` нет необходимости *добавлять специальные токены* во время токенизации.
153
+ Поэтому используем `add_special_tokens=False`:
154
+ ```python
155
+ terminator_ids = [
156
+ tokenizer.eos_token_id,
157
+ tokenizer.convert_tokens_to_ids("<end_of_turn>"),
158
+ ]
159
+ prompt_ids = tokenizer.encode(inputs, add_special_tokens=False, return_tensors='pt').to(model.device)
160
+ generated_ids = model.generate(
161
+ prompt_ids,
162
+ max_new_tokens=512,
163
+ eos_token_id=terminator_ids,
164
+ bos_token_id=tokenizer.bos_token_id,
165
+ )
166
+ generated_response = tokenizer.decode(generated_ids[0][prompt_ids.shape[-1]:], skip_special_tokens=False) # `skip_special_tokens=False` for debug
167
+ print(generated_response)
168
+ ```
169
+
170
+ Мы получаем генерацию в виде вызова функции:
171
+ ```
172
+ Вызов функции: {"name": "get_sunrise_sunset_times", "arguments": {"city": "Краснодар"}}<end_of_turn>
173
+ ```
174
+
175
+ Отлично, теперь мы можем получать и обрабатывать результаты с помощью нашей *вызываемой функции*, а затем предоставлять модели ответ *функции*:
176
+ ```python
177
+ history_messages = [
178
+ {"role": "system", "content": "Ты - полезный помощник, имеющий доступ к следующим функциям. Используйте их при необходимости - "},
179
+ {"role": "user", "content": "Привет, не мог бы ты сказать мне, во сколько в Краснодаре восходит солнце?"},
180
+ {"role": "function-call", "content": '{"name": "get_sunrise_sunset_times", "arguments": {"city": "Los Angeles"}}'},
181
+ {"role": "function-response", "content": '{"times_list": ["6:00", "18:00"]}'}, # гипотетический ответ от наш��й функции
182
+ ]
183
+ inputs = tokenizer.apply_chat_template(
184
+ history_messages,
185
+ tokenize=False,
186
+ add_generation_prompt=True, # добавление запроса для генерации
187
+ tools=[get_weather, get_sunrise_sunset_times], # наши функции (tools)
188
+ )
189
+ print(inputs)
190
+ ```
191
+
192
+ Давайте убедимся, что `inputs` верны:
193
+ ```
194
+ <bos><start_of_turn>user
195
+ Ты - полезный помощник, имеющий доступ к следующим функциям. Используйте их при необходимости - {
196
+ "name": "get_weather",
197
+ "description": "Функция, которая возвращает погоду в заданном городе.",
198
+ "parameters": {
199
+ "type": "object",
200
+ "properties": {
201
+ "city": {
202
+ "type": "string",
203
+ "description": "Город, для которого надо узнать погоду."
204
+ }
205
+ },
206
+ "required": [
207
+ "city"
208
+ ]
209
+ }
210
+ },
211
+ {
212
+ "name": "get_sunrise_sunset_times",
213
+ "description": "Функция, которая возвращает время восхода и заката для заданного города для текущей даты (дата от пользователя не требуется), в формате списка: [sunrise_time, sunset_time].",
214
+ "parameters": {
215
+ "type": "object",
216
+ "properties": {
217
+ "city": {
218
+ "type": "string",
219
+ "description": "Город, в котором можно узнать время восхода и захода солнца."
220
+ }
221
+ },
222
+ "required": [
223
+ "city"
224
+ ]
225
+ }
226
+ }
227
+ Привет, не мог бы ты сказать мне, во сколько в Краснодаре восходит солнце?<end_of_turn>
228
+ <start_of_turn>model
229
+ Вызов функции: {"name": "get_sunrise_sunset_times", "arguments": {"city": "Краснодар"}}<end_of_turn>
230
+ <start_of_turn>user
231
+ Ответ от функции: {"times_list": ["6:00", "18:00"]}<end_of_turn>
232
+ <start_of_turn>model
233
+ ```
234
+
235
+ Аналогично, мы генерируем ответ модели:
236
+ ```python
237
+ prompt_ids = tokenizer.encode(inputs, add_special_tokens=False, return_tensors='pt').to(model.device)
238
+ generated_ids = model.generate(
239
+ prompt_ids,
240
+ max_new_tokens=512,
241
+ eos_token_id=terminator_ids,
242
+ bos_token_id=tokenizer.bos_token_id,
243
+ )
244
+ generated_response = tokenizer.decode(generated_ids[0][prompt_ids.shape[-1]:], skip_special_tokens=False) # `skip_special_tokens=False` for debug
245
+ print(generated_response)
246
+ ```
247
+
248
+ В результате мы получаем ответ модели:
249
+ ```
250
+ В Краснодаре солнце восходит в 6:00 утра и заходит в 18:00 вечера.<end_of_turn>
251
+ ```
252
+
253
+ ## Использование через transformers `pipeline`
254
+
255
+ <details>
256
+ <summary>
257
+ Generation via pipeline
258
+ </summary>
259
+
260
+ ```python
261
+ from transformers import pipeline
262
+ generation_pipeline = pipeline(
263
+ "text-generation",
264
+ model="DiTy/gemma-2-9b-it-russian-function-calling-GGUF",
265
+ model_kwargs={
266
+ "torch_dtype": torch.bfloat16, # use float16 or float32 if bfloat16 is not supported for you.
267
+ "cache_dir": PATH_TO_MODEL_DIR, # OPTIONAL
268
+ },
269
+ device_map="auto",
270
+ )
271
+ history_messages = [
272
+ {"role": "system", "content": "Ты - полезный помощник, имеющий доступ к следующим функциям. Используйте их при необходимости - "},
273
+ {"role": "user", "content": "Привет, не мог бы ты сказать мне, во сколько в Краснодаре восходит солнце?"},
274
+ {"role": "function-call", "content": '{"name": "get_sunrise_sunset_times", "arguments": {"city": "Краснодар"}}'},
275
+ {"role": "function-response", "content": '{"times_list": ["6:00", "18:00"]}'}
276
+ ]
277
+ inputs = generation_pipeline.tokenizer.apply_chat_template(
278
+ history_messages,
279
+ tokenize=False,
280
+ add_generation_prompt=True,
281
+ tools=[get_weather, get_sunrise_sunset_times],
282
+ )
283
+ terminator_ids = [
284
+ generation_pipeline.tokenizer.eos_token_id,
285
+ generation_pipeline.tokenizer.convert_tokens_to_ids("<end_of_turn>")
286
+ ]
287
+ outputs = generation_pipeline(
288
+ inputs,
289
+ max_new_tokens=512,
290
+ eos_token_id=terminator_ids,
291
+ )
292
+ print(outputs[0]["generated_text"][len(inputs):])
293
+ ```
294
+
295
+ </details>
296
+
297
+ ## <a name="roles"></a>Prompt структура и ожидаемый контент
298
+
299
+ Для наиболее корректной работы модели предполагается, что будет использоваться `apply_chat_template`.
300
+ Необходимо передать историю сообщений в определенном формате.
301
+ ```python
302
+ history_messages = [
303
+ {"role": "...", "content": "..."},
304
+ ...
305
+ ]
306
+ ```
307
+
308
+ Для использования доступны следующие роли:
309
+
310
+ * `system` - это необязательная роль, ее содержимое всегда размещается в самом начале и перед перечислением функций, доступных модели (инструментов).
311
+ Вы всегда можете воспользоваться стандартным вариантом, который использовался во время обучения: ***"Ты - полезный помощник, имеющий доступ к следующим функциям. Используйте их при необходимости - "***
312
+ * `user` - запрос пользователя передается через эту роль.
313
+ * `function-call` - тело вызова функции передается через эту роль.
314
+ Хотя модель обучена генерировать вызов функции в виде ***"Вызов функции: {...}\<end_of_turn\>"***, вы все равно должны передать только тело ***"{...}"***
315
+ в поле *"content"*, поскольку используя `apply_chat_template`, постскриптум в инструкциях добавляется автоматически.
316
+ * `function-response` - в этой роли мы должны передать ответ нашей функции в поле *"content"* в виде словаря ***'{"name_returnable_value": value}'***.
317
+ * `model` - содержимое, относящееся к этой роли, считается сгенерированным текстом модели.
318
+
319
+
320
+ ### Структура истории чата для *Function Calling*
321
+
322
+ ```
323
+ [
324
+ {"role": "system", "content": "Ты - полезный помощник, имеющий доступ к следующим функциям. Используйте их при необходимости - "},
325
+ {"role": "user", "content": "Привет, не мог бы ты сказать мне, во сколько в Краснодаре восходит солнце?"},
326
+ {"role": "function-call", "content": '{"name": "get_sunrise_sunset_times", "arguments": {"city": "Краснодар"}}'},
327
+ {"role": "function-response", "content": '{"times_list": ["6:00", "18:00"]}'}
328
+ ]
329
+ ```
330
+
331
+ Это выглядит как:
332
+ ```
333
+ <bos><start_of_turn>user
334
+ Ты - полезный помощник, имеющий доступ к следующим функциям. Используйте их при необходимости - {
335
+ "name": "get_weather",
336
+ "description": "Функция, которая возвращает погоду в заданном городе.",
337
+ "parameters": {
338
+ "type": "object",
339
+ "properties": {
340
+ "city": {
341
+ "type": "string",
342
+ "description": "Город, для которого надо узнать погоду."
343
+ }
344
+ },
345
+ "required": [
346
+ "city"
347
+ ]
348
+ }
349
+ },
350
+ {
351
+ "name": "get_sunrise_sunset_times",
352
+ "description": "Функция, которая возвращает время восхода и заката для заданного города для текущей даты (дата от пользователя не требуется), в формате списка: [sunrise_time, sunset_time].",
353
+ "parameters": {
354
+ "type": "object",
355
+ "properties": {
356
+ "city": {
357
+ "type": "string",
358
+ "description": "Город, в котором можно узнать время восхода и захода солнца."
359
+ }
360
+ },
361
+ "required": [
362
+ "city"
363
+ ]
364
+ }
365
+ }
366
+ Привет, не мог бы ты сказать мне, во сколько в Краснодаре восходит солнце?<end_of_turn>
367
+ <start_of_turn>model
368
+ Вызов функции: {"name": "get_sunrise_sunset_times", "arguments": {"city": "Краснодар"}}<end_of_turn>
369
+ <start_of_turn>user
370
+ Ответ от функции: {"times_list": ["6:00", "18:00"]}<end_of_turn>
371
+ ```
372
+
373
+
374
+ ### Структура истории чата для обычного user-model шаблона
375
+
376
+ ```
377
+ [
378
+ {"role": "system", "content": "Ты добрый помощник"},
379
+ {"role": "user", "content": "Расскажи мне о Москве"}
380
+ ]
381
+ ```
382
+
383
+ Это выглядит как:
384
+ ```
385
+ <bos><start_of_turn>user
386
+ Ты добрый помощник
387
+ Расскажи мне о Москве<end_of_turn>
388
+ ```
389
+
390
+ ## <a name="eval"></a>Оценка моделей
391
+
392
+ В процессе обучения ошибка валидации была приближена к следующим значениям:
393
+
394
+ | **Model** | **Generation Language** | **Approximately Validation Loss** |
395
+ | :-----: | :-----: | :-----: |
396
+ | [DiTy/gemma-2-27b-it-function-calling-GGUF](https://huggingface.co/DiTy/gemma-2-27b-it-function-calling-GGUF) | EN | 0.47 |
397
+ | [**DiTy/gemma-2-9b-it-russian-function-calling-GGUF**](https://huggingface.co/DiTy/gemma-2-9b-it-russian-function-calling-GGUF) | **RU** | **0.57** |
398
+ | [DiTy/gemma-2-9b-it-function-calling-GGUF](https://huggingface.co/DiTy/gemma-2-9b-it-function-calling-GGUF) | EN | 0.5 |
399
+ | [DiTy/gemma-2-2b-it-function-calling](https://huggingface.co/DiTy/gemma-2-2b-it-function-calling) | EN | 0.66 |
400
+
401
+ ## Citation
402
+
403
+ ```none
404
+ @article{gemma_2024,
405
+ title={Gemma},
406
+ url={https://www.kaggle.com/m/3301},
407
+ DOI={10.34740/KAGGLE/M/3301},
408
+ publisher={Kaggle},
409
+ author={Gemma Team},
410
+ year={2024}
411
+ }
412
+ ```