Views
No views yet
pip install peft transformers bitsandbytes1import json
2import re
3from abc import ABC, abstractmethod
4from dataclasses import dataclass, field
5from typing import Any, Dict, List, Literal, Optional, Sequence, Set, Tuple, Union
6
7def calculate_gpa(grades: Sequence[str], hours: Sequence[int]) -> float:
8 grade_to_score = {"A": 4, "B": 3, "C": 2}
9 total_score, total_hour = 0, 0
10 for grade, hour in zip(grades, hours):
11 total_score += grade_to_score[grade] * hour
12 total_hour += hour
13 return round(total_score / total_hour, 2)
14
15tool_map = {"calculate_gpa": calculate_gpa}
16
17from transformers import AutoModelForCausalLM, AutoTokenizer, TextStreamer
18from peft import PeftModel
19
20tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2-1.5B-Instruct")
21model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2-1.5B-Instruct",
22 torch_dtype="auto", device_map="auto")
23
24model = PeftModel.from_pretrained(model, "svjack/Qwen2-1_5B_Function_Call_tiny_lora")
25streamer = TextStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)
26
27SLOTS = Sequence[Union[str, Set[str], Dict[str, str]]]
28
29
30DEFAULT_TOOL_PROMPT = (
31 "You have access to the following tools:\n{tool_text}"
32 "Use the following format if using a tool:\n"
33 "```\n"
34 "Action: tool name (one of [{tool_names}]).\n"
35 "Action Input: the input to the tool, in a JSON format representing the kwargs "
36 """(e.g. ```{{"input": "hello world", "num_beams": 5}}```).\n"""
37 "```\n"
38)
39
40def default_tool_formatter(tools: List[Dict[str, Any]]) -> str:
41 tool_text = ""
42 tool_names = []
43 for tool in tools:
44 param_text = ""
45 for name, param in tool["parameters"]["properties"].items():
46 required = ", required" if name in tool["parameters"].get("required", []) else ""
47 enum = ", should be one of [{}]".format(", ".join(param["enum"])) if param.get("enum", None) else ""
48 items = (
49 ", where each item should be {}".format(param["items"].get("type", "")) if param.get("items") else ""
50 )
51 param_text += " - {name} ({type}{required}): {desc}{enum}{items}\n".format(
52 name=name,
53 type=param.get("type", ""),
54 required=required,
55 desc=param.get("description", ""),
56 enum=enum,
57 items=items,
58 )
59
60 tool_text += "> Tool Name: {name}\nTool Description: {desc}\nTool Args:\n{args}\n".format(
61 name=tool["name"], desc=tool.get("description", ""), args=param_text
62 )
63 tool_names.append(tool["name"])
64
65 return DEFAULT_TOOL_PROMPT.format(tool_text=tool_text, tool_names=", ".join(tool_names))
66
67def default_tool_extractor(content: str) -> Union[str, List[Tuple[str, str]]]:
68 regex = re.compile(r"Action:\s*([a-zA-Z0-9_]+)\s*Action Input:\s*(.+?)(?=\s*Action:|\s*$)", re.DOTALL)
69 action_match: List[Tuple[str, str]] = re.findall(regex, content)
70 if not action_match:
71 return content
72
73 results = []
74 for match in action_match:
75 tool_name = match[0].strip()
76 tool_input = match[1].strip().strip('"').strip("```")
77 try:
78 arguments = json.loads(tool_input)
79 results.append((tool_name, json.dumps(arguments, ensure_ascii=False)))
80 except json.JSONDecodeError:
81 return content
82
83 return results
84
85#### Function tool defination
86tools = [
87 {
88 "type": "function",
89 "function": {
90 "name": "calculate_gpa",
91 "description": "Calculate the Grade Point Average (GPA) based on grades and credit hours",
92 "parameters": {
93 "type": "object",
94 "properties": {
95 "grades": {"type": "array", "items": {"type": "string"}, "description": "The grades"},
96 "hours": {"type": "array", "items": {"type": "integer"}, "description": "The credit hours"},
97 },
98 "required": ["grades", "hours"],
99 },
100 },
101 }
102 ]
103
104tools_input = list(map(lambda x: x["function"], tools))
105system_tool_prompt = default_tool_formatter(tools_input)
106#print(system_tool_prompt)
107
108def qwen_hf_predict(messages, qw_model = model,
109 tokenizer = tokenizer, streamer = streamer,
110 do_sample = True,
111 top_p = 0.95,
112 top_k = 40,
113 max_new_tokens = 512,
114 max_input_length = 3500,
115 temperature = 0.9,
116 repetition_penalty = 1.0,
117 device = "cuda"):
118
119 encodeds = tokenizer.apply_chat_template(messages, return_tensors="pt",
120 add_generation_prompt=True
121 )
122 model_inputs = encodeds.to(device)
123
124 generated_ids = qw_model.generate(model_inputs, max_new_tokens=max_new_tokens,
125 do_sample=do_sample,
126 streamer = streamer,
127 top_p = top_p,
128 top_k = top_k,
129 temperature = temperature,
130 repetition_penalty = repetition_penalty,
131 )
132 out = tokenizer.batch_decode(generated_ids)[0].split("<|im_start|>assistant")[-1].replace("<|im_end|>", "").strip()
133 return out
134
135messages = [
136 {
137 "role" :"system",
138 "content": system_tool_prompt
139 },
140 {"role": "user", "content": "My grades are A, A, B, and C. The credit hours are 3, 4, 3, and 2."}
141]
142
143out = qwen_hf_predict(messages)
144tool_out = default_tool_extractor(out)
145print(tool_out)
146
147name, arguments = tool_out[0][0], json.loads(tool_out[0][1])
148tool_result = tool_map[name](**arguments)
149print(tool_result)
150
151messages.append(
152 {
153 "role" :"assistant",
154 "content": out
155 }
156)
157
158messages.append({"role": "tool", "content": json.dumps({"gpa": tool_result}, ensure_ascii=False)})
159
160final_out = qwen_hf_predict(messages)
161print(final_out)Action: calculate_gpa
Action Input: {"grades": ["A", "A", "B", "C"], "hours": [3, 4, 3, 2]}
[('calculate_gpa', '{"grades": ["A", "A", "B", "C"], "hours": [3, 4, 3, 2]}')]
3.42
Your calculated GPA is 3.42.1messages = [
2 {
3 "role" :"system",
4 "content": system_tool_prompt
5 },
6 {"role": "user", "content": "我的成绩分别是A,A,B,C学分分别是3, 4, 3,和2"}
7]
8
9out = qwen_hf_predict(messages)
10tool_out = default_tool_extractor(out)
11print(tool_out)
12
13name, arguments = tool_out[0][0], json.loads(tool_out[0][1])
14tool_result = tool_map[name](**arguments)
15print(tool_result)
16
17messages.append(
18 {
19 "role" :"assistant",
20 "content": out
21 }
22)
23
24messages.append({"role": "tool", "content": json.dumps({"gpa": tool_result}, ensure_ascii=False)})
25
26final_out = qwen_hf_predict(messages)
27print(final_out)Action: calculate_gpa
Action Input: {"grades": ["A", "A", "B", "C"], "hours": [3, 4, 3, 2]}
[('calculate_gpa', '{"grades": ["A", "A", "B", "C"], "hours": [3, 4, 3, 2]}')]
3.42
你的GPA是3.42。