Upload folder using huggingface_hub
Browse files- .gitattributes +1 -0
- README.md +19 -0
- added_tokens.json +24 -0
- config.json +36 -0
- merges.txt +0 -0
- model-00001-of-00004.safetensors +3 -0
- model-00002-of-00004.safetensors +3 -0
- model-00003-of-00004.safetensors +3 -0
- model-00004-of-00004.safetensors +3 -0
- model.safetensors.index.json +0 -0
- special_tokens_map.json +31 -0
- tokenizer.json +3 -0
- tokenizer_config.json +209 -0
- vocab.json +0 -0
- xlam_tool_call_parser.py +198 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
tokenizer.json filter=lfs diff=lfs merge=lfs -text
|
README.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: cc-by-nc-4.0
|
| 3 |
+
datasets:
|
| 4 |
+
- Salesforce/xlam-function-calling-60k
|
| 5 |
+
language:
|
| 6 |
+
- en
|
| 7 |
+
pipeline_tag: text-generation
|
| 8 |
+
tags:
|
| 9 |
+
- function-calling
|
| 10 |
+
- LLM Agent
|
| 11 |
+
- tool-use
|
| 12 |
+
- llama
|
| 13 |
+
- qwen
|
| 14 |
+
- pytorch
|
| 15 |
+
- LLaMA-factory
|
| 16 |
+
- mlx
|
| 17 |
+
library_name: mlx
|
| 18 |
+
base_model: Salesforce/xLAM-2-32b-fc-r
|
| 19 |
+
---
|
added_tokens.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"</tool_call>": 151658,
|
| 3 |
+
"<tool_call>": 151657,
|
| 4 |
+
"<|box_end|>": 151649,
|
| 5 |
+
"<|box_start|>": 151648,
|
| 6 |
+
"<|endoftext|>": 151643,
|
| 7 |
+
"<|file_sep|>": 151664,
|
| 8 |
+
"<|fim_middle|>": 151660,
|
| 9 |
+
"<|fim_pad|>": 151662,
|
| 10 |
+
"<|fim_prefix|>": 151659,
|
| 11 |
+
"<|fim_suffix|>": 151661,
|
| 12 |
+
"<|im_end|>": 151645,
|
| 13 |
+
"<|im_start|>": 151644,
|
| 14 |
+
"<|image_pad|>": 151655,
|
| 15 |
+
"<|object_ref_end|>": 151647,
|
| 16 |
+
"<|object_ref_start|>": 151646,
|
| 17 |
+
"<|quad_end|>": 151651,
|
| 18 |
+
"<|quad_start|>": 151650,
|
| 19 |
+
"<|repo_name|>": 151663,
|
| 20 |
+
"<|video_pad|>": 151656,
|
| 21 |
+
"<|vision_end|>": 151653,
|
| 22 |
+
"<|vision_pad|>": 151654,
|
| 23 |
+
"<|vision_start|>": 151652
|
| 24 |
+
}
|
config.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"architectures": [
|
| 3 |
+
"Qwen2ForCausalLM"
|
| 4 |
+
],
|
| 5 |
+
"attention_dropout": 0.0,
|
| 6 |
+
"bos_token_id": 151643,
|
| 7 |
+
"eos_token_id": 151645,
|
| 8 |
+
"hidden_act": "silu",
|
| 9 |
+
"hidden_size": 5120,
|
| 10 |
+
"initializer_range": 0.02,
|
| 11 |
+
"intermediate_size": 27648,
|
| 12 |
+
"max_position_embeddings": 32768,
|
| 13 |
+
"max_window_layers": 70,
|
| 14 |
+
"model_type": "qwen2",
|
| 15 |
+
"num_attention_heads": 40,
|
| 16 |
+
"num_hidden_layers": 64,
|
| 17 |
+
"num_key_value_heads": 8,
|
| 18 |
+
"quantization": {
|
| 19 |
+
"group_size": 64,
|
| 20 |
+
"bits": 4
|
| 21 |
+
},
|
| 22 |
+
"quantization_config": {
|
| 23 |
+
"group_size": 64,
|
| 24 |
+
"bits": 4
|
| 25 |
+
},
|
| 26 |
+
"rms_norm_eps": 1e-06,
|
| 27 |
+
"rope_scaling": null,
|
| 28 |
+
"rope_theta": 1000000.0,
|
| 29 |
+
"sliding_window": null,
|
| 30 |
+
"tie_word_embeddings": false,
|
| 31 |
+
"torch_dtype": "bfloat16",
|
| 32 |
+
"transformers_version": "4.46.1",
|
| 33 |
+
"use_cache": false,
|
| 34 |
+
"use_sliding_window": false,
|
| 35 |
+
"vocab_size": 152064
|
| 36 |
+
}
|
merges.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
model-00001-of-00004.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e3d14ef29b484d1d6155870f301f07fdf81b26a3a06650b28d22aaf71916f25b
|
| 3 |
+
size 5366583057
|
model-00002-of-00004.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:1420f801a13d8f7624768a485305ac8e0a85e4f51665b6174c474b4730b384b9
|
| 3 |
+
size 5335713350
|
model-00003-of-00004.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:765644815115ab7e174db79b7d6af6ddd14b0efb40741dc8c46b2ed64298c682
|
| 3 |
+
size 5366642308
|
model-00004-of-00004.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e8396e5ec01844a656744516ea0ba7d15a2621d085c97bb101058041ce601a80
|
| 3 |
+
size 2362540963
|
model.safetensors.index.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
special_tokens_map.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"additional_special_tokens": [
|
| 3 |
+
"<|im_start|>",
|
| 4 |
+
"<|im_end|>",
|
| 5 |
+
"<|object_ref_start|>",
|
| 6 |
+
"<|object_ref_end|>",
|
| 7 |
+
"<|box_start|>",
|
| 8 |
+
"<|box_end|>",
|
| 9 |
+
"<|quad_start|>",
|
| 10 |
+
"<|quad_end|>",
|
| 11 |
+
"<|vision_start|>",
|
| 12 |
+
"<|vision_end|>",
|
| 13 |
+
"<|vision_pad|>",
|
| 14 |
+
"<|image_pad|>",
|
| 15 |
+
"<|video_pad|>"
|
| 16 |
+
],
|
| 17 |
+
"eos_token": {
|
| 18 |
+
"content": "<|im_end|>",
|
| 19 |
+
"lstrip": false,
|
| 20 |
+
"normalized": false,
|
| 21 |
+
"rstrip": false,
|
| 22 |
+
"single_word": false
|
| 23 |
+
},
|
| 24 |
+
"pad_token": {
|
| 25 |
+
"content": "<|endoftext|>",
|
| 26 |
+
"lstrip": false,
|
| 27 |
+
"normalized": false,
|
| 28 |
+
"rstrip": false,
|
| 29 |
+
"single_word": false
|
| 30 |
+
}
|
| 31 |
+
}
|
tokenizer.json
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:9c5ae00e602b8860cbd784ba82a8aa14e8feecec692e7076590d014d7b7fdafa
|
| 3 |
+
size 11421896
|
tokenizer_config.json
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"add_bos_token": false,
|
| 3 |
+
"add_prefix_space": false,
|
| 4 |
+
"added_tokens_decoder": {
|
| 5 |
+
"151643": {
|
| 6 |
+
"content": "<|endoftext|>",
|
| 7 |
+
"lstrip": false,
|
| 8 |
+
"normalized": false,
|
| 9 |
+
"rstrip": false,
|
| 10 |
+
"single_word": false,
|
| 11 |
+
"special": true
|
| 12 |
+
},
|
| 13 |
+
"151644": {
|
| 14 |
+
"content": "<|im_start|>",
|
| 15 |
+
"lstrip": false,
|
| 16 |
+
"normalized": false,
|
| 17 |
+
"rstrip": false,
|
| 18 |
+
"single_word": false,
|
| 19 |
+
"special": true
|
| 20 |
+
},
|
| 21 |
+
"151645": {
|
| 22 |
+
"content": "<|im_end|>",
|
| 23 |
+
"lstrip": false,
|
| 24 |
+
"normalized": false,
|
| 25 |
+
"rstrip": false,
|
| 26 |
+
"single_word": false,
|
| 27 |
+
"special": true
|
| 28 |
+
},
|
| 29 |
+
"151646": {
|
| 30 |
+
"content": "<|object_ref_start|>",
|
| 31 |
+
"lstrip": false,
|
| 32 |
+
"normalized": false,
|
| 33 |
+
"rstrip": false,
|
| 34 |
+
"single_word": false,
|
| 35 |
+
"special": true
|
| 36 |
+
},
|
| 37 |
+
"151647": {
|
| 38 |
+
"content": "<|object_ref_end|>",
|
| 39 |
+
"lstrip": false,
|
| 40 |
+
"normalized": false,
|
| 41 |
+
"rstrip": false,
|
| 42 |
+
"single_word": false,
|
| 43 |
+
"special": true
|
| 44 |
+
},
|
| 45 |
+
"151648": {
|
| 46 |
+
"content": "<|box_start|>",
|
| 47 |
+
"lstrip": false,
|
| 48 |
+
"normalized": false,
|
| 49 |
+
"rstrip": false,
|
| 50 |
+
"single_word": false,
|
| 51 |
+
"special": true
|
| 52 |
+
},
|
| 53 |
+
"151649": {
|
| 54 |
+
"content": "<|box_end|>",
|
| 55 |
+
"lstrip": false,
|
| 56 |
+
"normalized": false,
|
| 57 |
+
"rstrip": false,
|
| 58 |
+
"single_word": false,
|
| 59 |
+
"special": true
|
| 60 |
+
},
|
| 61 |
+
"151650": {
|
| 62 |
+
"content": "<|quad_start|>",
|
| 63 |
+
"lstrip": false,
|
| 64 |
+
"normalized": false,
|
| 65 |
+
"rstrip": false,
|
| 66 |
+
"single_word": false,
|
| 67 |
+
"special": true
|
| 68 |
+
},
|
| 69 |
+
"151651": {
|
| 70 |
+
"content": "<|quad_end|>",
|
| 71 |
+
"lstrip": false,
|
| 72 |
+
"normalized": false,
|
| 73 |
+
"rstrip": false,
|
| 74 |
+
"single_word": false,
|
| 75 |
+
"special": true
|
| 76 |
+
},
|
| 77 |
+
"151652": {
|
| 78 |
+
"content": "<|vision_start|>",
|
| 79 |
+
"lstrip": false,
|
| 80 |
+
"normalized": false,
|
| 81 |
+
"rstrip": false,
|
| 82 |
+
"single_word": false,
|
| 83 |
+
"special": true
|
| 84 |
+
},
|
| 85 |
+
"151653": {
|
| 86 |
+
"content": "<|vision_end|>",
|
| 87 |
+
"lstrip": false,
|
| 88 |
+
"normalized": false,
|
| 89 |
+
"rstrip": false,
|
| 90 |
+
"single_word": false,
|
| 91 |
+
"special": true
|
| 92 |
+
},
|
| 93 |
+
"151654": {
|
| 94 |
+
"content": "<|vision_pad|>",
|
| 95 |
+
"lstrip": false,
|
| 96 |
+
"normalized": false,
|
| 97 |
+
"rstrip": false,
|
| 98 |
+
"single_word": false,
|
| 99 |
+
"special": true
|
| 100 |
+
},
|
| 101 |
+
"151655": {
|
| 102 |
+
"content": "<|image_pad|>",
|
| 103 |
+
"lstrip": false,
|
| 104 |
+
"normalized": false,
|
| 105 |
+
"rstrip": false,
|
| 106 |
+
"single_word": false,
|
| 107 |
+
"special": true
|
| 108 |
+
},
|
| 109 |
+
"151656": {
|
| 110 |
+
"content": "<|video_pad|>",
|
| 111 |
+
"lstrip": false,
|
| 112 |
+
"normalized": false,
|
| 113 |
+
"rstrip": false,
|
| 114 |
+
"single_word": false,
|
| 115 |
+
"special": true
|
| 116 |
+
},
|
| 117 |
+
"151657": {
|
| 118 |
+
"content": "<tool_call>",
|
| 119 |
+
"lstrip": false,
|
| 120 |
+
"normalized": false,
|
| 121 |
+
"rstrip": false,
|
| 122 |
+
"single_word": false,
|
| 123 |
+
"special": false
|
| 124 |
+
},
|
| 125 |
+
"151658": {
|
| 126 |
+
"content": "</tool_call>",
|
| 127 |
+
"lstrip": false,
|
| 128 |
+
"normalized": false,
|
| 129 |
+
"rstrip": false,
|
| 130 |
+
"single_word": false,
|
| 131 |
+
"special": false
|
| 132 |
+
},
|
| 133 |
+
"151659": {
|
| 134 |
+
"content": "<|fim_prefix|>",
|
| 135 |
+
"lstrip": false,
|
| 136 |
+
"normalized": false,
|
| 137 |
+
"rstrip": false,
|
| 138 |
+
"single_word": false,
|
| 139 |
+
"special": false
|
| 140 |
+
},
|
| 141 |
+
"151660": {
|
| 142 |
+
"content": "<|fim_middle|>",
|
| 143 |
+
"lstrip": false,
|
| 144 |
+
"normalized": false,
|
| 145 |
+
"rstrip": false,
|
| 146 |
+
"single_word": false,
|
| 147 |
+
"special": false
|
| 148 |
+
},
|
| 149 |
+
"151661": {
|
| 150 |
+
"content": "<|fim_suffix|>",
|
| 151 |
+
"lstrip": false,
|
| 152 |
+
"normalized": false,
|
| 153 |
+
"rstrip": false,
|
| 154 |
+
"single_word": false,
|
| 155 |
+
"special": false
|
| 156 |
+
},
|
| 157 |
+
"151662": {
|
| 158 |
+
"content": "<|fim_pad|>",
|
| 159 |
+
"lstrip": false,
|
| 160 |
+
"normalized": false,
|
| 161 |
+
"rstrip": false,
|
| 162 |
+
"single_word": false,
|
| 163 |
+
"special": false
|
| 164 |
+
},
|
| 165 |
+
"151663": {
|
| 166 |
+
"content": "<|repo_name|>",
|
| 167 |
+
"lstrip": false,
|
| 168 |
+
"normalized": false,
|
| 169 |
+
"rstrip": false,
|
| 170 |
+
"single_word": false,
|
| 171 |
+
"special": false
|
| 172 |
+
},
|
| 173 |
+
"151664": {
|
| 174 |
+
"content": "<|file_sep|>",
|
| 175 |
+
"lstrip": false,
|
| 176 |
+
"normalized": false,
|
| 177 |
+
"rstrip": false,
|
| 178 |
+
"single_word": false,
|
| 179 |
+
"special": false
|
| 180 |
+
}
|
| 181 |
+
},
|
| 182 |
+
"additional_special_tokens": [
|
| 183 |
+
"<|im_start|>",
|
| 184 |
+
"<|im_end|>",
|
| 185 |
+
"<|object_ref_start|>",
|
| 186 |
+
"<|object_ref_end|>",
|
| 187 |
+
"<|box_start|>",
|
| 188 |
+
"<|box_end|>",
|
| 189 |
+
"<|quad_start|>",
|
| 190 |
+
"<|quad_end|>",
|
| 191 |
+
"<|vision_start|>",
|
| 192 |
+
"<|vision_end|>",
|
| 193 |
+
"<|vision_pad|>",
|
| 194 |
+
"<|image_pad|>",
|
| 195 |
+
"<|video_pad|>"
|
| 196 |
+
],
|
| 197 |
+
"bos_token": null,
|
| 198 |
+
"chat_template": "{# System message #}\n{{- \"<|im_start|>system\\n\" }}\n{%- if messages[0]['role'] == 'system' %}\n {%- set system_message = messages[0]['content'] | trim %}\n {%- set messages = messages[1:] %}\n {{- system_message + \"\\n\" }}\n{%- else %}\n {%- set system_message = \"You are a helpful assistant that can use tools. You are developed by Salesforce xLAM team.\" %}\n {% set format_instruction %}You have access to a set of tools. When using tools, make calls in a single JSON array: \n\n[{\"name\": \"tool_call_name\", \"arguments\": {\"arg1\": \"value1\", \"arg2\": \"value2\"}}, ... (additional parallel tool calls as needed)]\n\nIf no tool is suitable, state that explicitly. If the user's input lacks required parameters, ask for clarification. Do not interpret or respond until tool results are returned. Once they are available, process them or make additional calls if needed. For tasks that don't require tools, such as casual conversation or general advice, respond directly in plain text. The available tools are:{% endset %}\n {{- system_message + \"\\n\" }}\n {%- if tools is not none %}\n {{- format_instruction + \"\\n\\n\" }}\n {%- endif %}\n{%- endif %}\n\n{%- if tools is not none %}\n {%- for func in tools %}\n {{- func | tojson(indent=4) }}\n {{- \"\\n\\n\" }}\n {%- endfor %}\n{%- endif %}\n{{- \"<|im_end|>\" }}\n{%- for message in messages %}\n {%- if message['role'] == 'tool' %}\n {{- \"<|im_start|>tool\\n\" }}\n {%- if message.content is defined and message.content.content is defined %}\n {%- set content = message.content.content %}\n {%- else %}\n {%- set content = message.content %}\n {%- endif %}\n {%- if content is mapping or content is iterable and content is not string %}\n {{- content | tojson }}\n {%- else %}\n {{- content }}\n {%- endif %}\n {{- \"<|im_end|>\" }}\n {%- elif 'tool_calls' in message %}\n {{- \"<|im_start|>assistant\\n\" }}\n {%- if message['tool_calls'] %}\n {{- \"[\" }}\n {%- for tool_call in message.tool_calls %}\n {%- set out = tool_call.function | tojson %}\n {{- out }}\n {%- if not loop.last %}\n {{- \", \" }}\n {%- endif %}\n {%- endfor %}\n {{- \"]\"}}\n {%- elif message['content'] %}\n {{- message['content'] | trim }}\n {%- else %}\n {{- \"[]\\n\" }}\n {%- endif %}\n {{- \"<|im_end|>\" }}\n {%- else %}\n {{- \"<|im_start|>\" + message['role'] + \"\\n\" + message['content'] | trim + \"<|im_end|>\" }}\n {%- endif %}\n{%- endfor %}\n\n{%- if add_generation_prompt %}\n {{- \"<|im_start|>assistant\\n\" }}\n{%- endif %}\n",
|
| 199 |
+
"clean_up_tokenization_spaces": false,
|
| 200 |
+
"eos_token": "<|im_end|>",
|
| 201 |
+
"errors": "replace",
|
| 202 |
+
"extra_special_tokens": {},
|
| 203 |
+
"model_max_length": 16384,
|
| 204 |
+
"pad_token": "<|endoftext|>",
|
| 205 |
+
"padding_side": "right",
|
| 206 |
+
"split_special_tokens": false,
|
| 207 |
+
"tokenizer_class": "Qwen2Tokenizer",
|
| 208 |
+
"unk_token": null
|
| 209 |
+
}
|
vocab.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
xlam_tool_call_parser.py
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
import re
|
| 3 |
+
from typing import Dict, List, Sequence, Union
|
| 4 |
+
import partial_json_parser
|
| 5 |
+
from partial_json_parser.core.options import Allow
|
| 6 |
+
|
| 7 |
+
from vllm.entrypoints.openai.protocol import (
|
| 8 |
+
ChatCompletionRequest, DeltaMessage, DeltaToolCall,
|
| 9 |
+
DeltaFunctionCall, ExtractedToolCallInformation, ToolCall, FunctionCall
|
| 10 |
+
)
|
| 11 |
+
from vllm.entrypoints.openai.tool_parsers.abstract_tool_parser import ToolParser, ToolParserManager
|
| 12 |
+
from vllm.utils import random_uuid
|
| 13 |
+
from vllm.logger import init_logger
|
| 14 |
+
from transformers import PreTrainedTokenizerBase
|
| 15 |
+
from vllm.entrypoints.openai.tool_parsers.utils import (find_common_prefix,
|
| 16 |
+
is_complete_json,
|
| 17 |
+
partial_json_loads)
|
| 18 |
+
|
| 19 |
+
logger = init_logger(__name__)
|
| 20 |
+
|
| 21 |
+
@ToolParserManager.register_module("xlam")
|
| 22 |
+
class xLAMToolParser(ToolParser):
|
| 23 |
+
def __init__(self, tokenizer: PreTrainedTokenizerBase):
|
| 24 |
+
super().__init__(tokenizer)
|
| 25 |
+
# State for streaming mode
|
| 26 |
+
self.prev_tool_calls: List[Dict] = []
|
| 27 |
+
self.current_tools_sent: List[bool] = []
|
| 28 |
+
self.streamed_args: List[str] = []
|
| 29 |
+
# Remove regex since we're parsing direct JSON
|
| 30 |
+
|
| 31 |
+
def extract_tool_calls(
|
| 32 |
+
self,
|
| 33 |
+
model_output: str,
|
| 34 |
+
request: ChatCompletionRequest
|
| 35 |
+
) -> ExtractedToolCallInformation:
|
| 36 |
+
try:
|
| 37 |
+
# Modified: Direct JSON parsing without looking for ```
|
| 38 |
+
if not model_output.strip().startswith('['):
|
| 39 |
+
return ExtractedToolCallInformation(
|
| 40 |
+
tools_called=False,
|
| 41 |
+
tool_calls=[],
|
| 42 |
+
content=model_output
|
| 43 |
+
)
|
| 44 |
+
|
| 45 |
+
tool_calls_data = json.loads(model_output)
|
| 46 |
+
tool_calls: List[ToolCall] = []
|
| 47 |
+
|
| 48 |
+
for idx, call in enumerate(tool_calls_data):
|
| 49 |
+
tool_call = ToolCall(
|
| 50 |
+
id=f"call_{idx}_{random_uuid()}",
|
| 51 |
+
type="function",
|
| 52 |
+
function=FunctionCall(
|
| 53 |
+
name=call["name"],
|
| 54 |
+
arguments=json.dumps(call["arguments"])
|
| 55 |
+
)
|
| 56 |
+
)
|
| 57 |
+
tool_calls.append(tool_call)
|
| 58 |
+
|
| 59 |
+
return ExtractedToolCallInformation(
|
| 60 |
+
tools_called=True,
|
| 61 |
+
tool_calls=tool_calls,
|
| 62 |
+
content=None
|
| 63 |
+
)
|
| 64 |
+
|
| 65 |
+
except Exception:
|
| 66 |
+
logger.exception("Error extracting tool calls")
|
| 67 |
+
return ExtractedToolCallInformation(
|
| 68 |
+
tools_called=False,
|
| 69 |
+
tool_calls=[],
|
| 70 |
+
content=model_output
|
| 71 |
+
)
|
| 72 |
+
|
| 73 |
+
def extract_tool_calls_streaming(
|
| 74 |
+
self,
|
| 75 |
+
previous_text: str,
|
| 76 |
+
current_text: str,
|
| 77 |
+
delta_text: str,
|
| 78 |
+
previous_token_ids: Sequence[int],
|
| 79 |
+
current_token_ids: Sequence[int],
|
| 80 |
+
delta_token_ids: Sequence[int],
|
| 81 |
+
request: ChatCompletionRequest,
|
| 82 |
+
) -> Union[DeltaMessage, None]:
|
| 83 |
+
if not current_text.strip().startswith('['):
|
| 84 |
+
return DeltaMessage(content=delta_text)
|
| 85 |
+
|
| 86 |
+
flags = Allow.ALL if self.current_tool_name_sent else Allow.ALL & ~Allow.STR
|
| 87 |
+
|
| 88 |
+
try:
|
| 89 |
+
tool_call_arr = []
|
| 90 |
+
is_complete = []
|
| 91 |
+
try:
|
| 92 |
+
# Parse the JSON array
|
| 93 |
+
start_idx = 0
|
| 94 |
+
while start_idx < len(current_text):
|
| 95 |
+
obj, end_idx = partial_json_loads(current_text[start_idx:], flags)
|
| 96 |
+
is_complete.append(
|
| 97 |
+
is_complete_json(current_text[start_idx:start_idx + end_idx])
|
| 98 |
+
)
|
| 99 |
+
start_idx += end_idx
|
| 100 |
+
tool_call_arr.append(obj)
|
| 101 |
+
except partial_json_parser.core.exceptions.MalformedJSON:
|
| 102 |
+
logger.debug('not enough tokens to parse into JSON yet')
|
| 103 |
+
return None
|
| 104 |
+
|
| 105 |
+
# Get current tool call based on state
|
| 106 |
+
current_tool_call: Dict = tool_call_arr[self.current_tool_id] \
|
| 107 |
+
if len(tool_call_arr) > 0 else {}
|
| 108 |
+
|
| 109 |
+
# Case 1: No tools parsed yet
|
| 110 |
+
if len(tool_call_arr) == 0:
|
| 111 |
+
return None
|
| 112 |
+
|
| 113 |
+
# Case 2: Starting a new tool in array
|
| 114 |
+
elif (len(tool_call_arr) > 0
|
| 115 |
+
and len(tool_call_arr) > self.current_tool_id + 1):
|
| 116 |
+
|
| 117 |
+
# Handle any remaining arguments from previous tool
|
| 118 |
+
if self.current_tool_id >= 0:
|
| 119 |
+
cur_arguments = current_tool_call.get("arguments")
|
| 120 |
+
if cur_arguments:
|
| 121 |
+
cur_args_json = json.dumps(cur_arguments)
|
| 122 |
+
sent = len(self.streamed_args[self.current_tool_id])
|
| 123 |
+
argument_diff = cur_args_json[sent:]
|
| 124 |
+
|
| 125 |
+
if argument_diff:
|
| 126 |
+
delta = DeltaMessage(tool_calls=[
|
| 127 |
+
DeltaToolCall(
|
| 128 |
+
index=self.current_tool_id,
|
| 129 |
+
function=DeltaFunctionCall(
|
| 130 |
+
arguments=argument_diff
|
| 131 |
+
).model_dump(exclude_none=True)
|
| 132 |
+
)
|
| 133 |
+
])
|
| 134 |
+
self.streamed_args[self.current_tool_id] += argument_diff
|
| 135 |
+
return delta
|
| 136 |
+
|
| 137 |
+
# Setup new tool
|
| 138 |
+
self.current_tool_id = len(tool_call_arr) - 1
|
| 139 |
+
self.current_tools_sent.append(False)
|
| 140 |
+
self.streamed_args.append("")
|
| 141 |
+
logger.debug("starting new tool %d", self.current_tool_id)
|
| 142 |
+
return None
|
| 143 |
+
|
| 144 |
+
# Case 3: Send tool name if not sent yet
|
| 145 |
+
elif not self.current_tools_sent[self.current_tool_id]:
|
| 146 |
+
function_name = current_tool_call.get("name")
|
| 147 |
+
if function_name:
|
| 148 |
+
delta = DeltaMessage(tool_calls=[
|
| 149 |
+
DeltaToolCall(
|
| 150 |
+
index=self.current_tool_id,
|
| 151 |
+
type="function",
|
| 152 |
+
id=f"call_{self.current_tool_id}_{random_uuid()}",
|
| 153 |
+
function=DeltaFunctionCall(
|
| 154 |
+
name=function_name
|
| 155 |
+
).model_dump(exclude_none=True)
|
| 156 |
+
)
|
| 157 |
+
])
|
| 158 |
+
self.current_tools_sent[self.current_tool_id] = True
|
| 159 |
+
return delta
|
| 160 |
+
return None
|
| 161 |
+
|
| 162 |
+
# Case 4: Stream arguments
|
| 163 |
+
else:
|
| 164 |
+
cur_arguments = current_tool_call.get("arguments")
|
| 165 |
+
if cur_arguments:
|
| 166 |
+
sent = len(self.streamed_args[self.current_tool_id])
|
| 167 |
+
cur_args_json = json.dumps(cur_arguments)
|
| 168 |
+
prev_arguments = self.prev_tool_calls[self.current_tool_id].get("arguments")
|
| 169 |
+
|
| 170 |
+
argument_diff = None
|
| 171 |
+
if is_complete[self.current_tool_id]:
|
| 172 |
+
argument_diff = cur_args_json[sent:]
|
| 173 |
+
elif prev_arguments:
|
| 174 |
+
prev_args_json = json.dumps(prev_arguments)
|
| 175 |
+
if cur_args_json != prev_args_json:
|
| 176 |
+
prefix = find_common_prefix(prev_args_json, cur_args_json)
|
| 177 |
+
argument_diff = prefix[sent:]
|
| 178 |
+
|
| 179 |
+
if argument_diff is not None:
|
| 180 |
+
delta = DeltaMessage(tool_calls=[
|
| 181 |
+
DeltaToolCall(
|
| 182 |
+
index=self.current_tool_id,
|
| 183 |
+
function=DeltaFunctionCall(
|
| 184 |
+
arguments=argument_diff
|
| 185 |
+
).model_dump(exclude_none=True)
|
| 186 |
+
)
|
| 187 |
+
])
|
| 188 |
+
self.streamed_args[self.current_tool_id] += argument_diff
|
| 189 |
+
return delta
|
| 190 |
+
|
| 191 |
+
self.prev_tool_calls = tool_call_arr
|
| 192 |
+
return None
|
| 193 |
+
|
| 194 |
+
except Exception:
|
| 195 |
+
logger.exception("Error in streaming tool calls")
|
| 196 |
+
logger.debug("Skipping chunk due to streaming error")
|
| 197 |
+
return None
|
| 198 |
+
|