Views
No views yet

| Model | IFEval - TH | IFEval - EN | MT-Bench TH | MT-Bench EN | Thai Code-Switching (t=0.7) | Thai Code-Switching (t=1.0) | FunctionCall-TH | FunctionCall-EN |
|---|---|---|---|---|---|---|---|---|
| Typhoon2 1b instruct | 52.46% | 53.35% | 3.9725 | 5.2125 | 96.4% | 88% | 34.96% | 45.60% |
| Qwen2.5 1.5b instruct | 44.42% | 48.45% | 2.9395 | 6.9343 | 82.6% | 20.6% | 13.83% | 17.88% |
| llama3.2 1b instruct | 31.76% | 51.15% | 2.5824 | 6.229 | 97.8% | 22.6% | 29.88% | 36.50% |
1from transformers import AutoTokenizer, AutoModelForCausalLM
2import torch
3
4model_id = "scb10x/llama3.2-typhoon2-1b-instruct"
5
6tokenizer = AutoTokenizer.from_pretrained(model_id)
7model = AutoModelForCausalLM.from_pretrained(
8 model_id,
9 torch_dtype=torch.bfloat16,
10 device_map="auto",
11)
12
13messages = [
14 {"role": "system", "content": "You are a male AI assistant named Typhoon created by SCB 10X to be helpful, harmless, and honest. Typhoon is happy to help with analysis, question answering, math, coding, creative writing, teaching, role-play, general discussion, and all sorts of other tasks. Typhoon responds directly to all human messages without unnecessary affirmations or filler phrases like “Certainly!”, “Of course!”, “Absolutely!”, “Great!”, “Sure!”, etc. Specifically, Typhoon avoids starting responses with the word “Certainly” in any way. Typhoon follows this information in all languages, and always responds to the user in the language they use or request. Typhoon is now being connected with a human. Write in fluid, conversational prose, Show genuine interest in understanding requests, Express appropriate emotions and empathy. Also showing information in term that is easy to understand and visualized."},
15 {"role": "user", "content": "ขอสูตรไก่ย่าง"},
16]
17
18input_ids = tokenizer.apply_chat_template(
19 messages,
20 add_generation_prompt=True,
21 return_tensors="pt"
22).to(model.device)
23
24terminators = [
25 tokenizer.eos_token_id,
26 tokenizer.convert_tokens_to_ids("<|eot_id|>")
27]
28## Typhoon 1b need low temperature to inference.
29outputs = model.generate(
30 input_ids,
31 max_new_tokens=512,
32 eos_token_id=terminators,
33 do_sample=True,
34 temperature=0.4,
35 top_p=0.9,
36)
37response = outputs[0][input_ids.shape[-1]:]
38print(tokenizer.decode(response, skip_special_tokens=True))1import torch
2from transformers import AutoModelForCausalLM, AutoTokenizer
3import ast
4model_name = "scb10x/llama3.2-typhoon2-1b-instruct"
5tokenizer = AutoTokenizer.from_pretrained(model_name)
6model = AutoModelForCausalLM.from_pretrained(
7 model_name, torch_dtype=torch.bfloat16, device_map="auto",
8)
9
10get_weather_api = {
11 "name": "get_weather",
12 "description": "Get the current weather for a location",
13 "parameters": {
14 "type": "object",
15 "properties": {
16 "location": {
17 "type": "string",
18 "description": "The city and state, e.g. San Francisco, New York",
19 },
20 "unit": {
21 "type": "string",
22 "enum": ["celsius", "fahrenheit"],
23 "description": "The unit of temperature to return",
24 },
25 },
26 "required": ["location"],
27 },
28}
29
30
31search_api = {
32 "name": "search",
33 "description": "Search for information on the internet",
34 "parameters": {
35 "type": "object",
36 "properties": {
37 "query": {
38 "type": "string",
39 "description": "The search query, e.g. 'latest news on AI'",
40 }
41 },
42 "required": ["query"],
43 },
44}
45
46get_stock = {
47 "name": "get_stock_price",
48 "description": "Get the stock price",
49 "parameters": {
50 "type": "object",
51 "properties": {
52 "symbol": {
53 "type": "string",
54 "description": "The stock symbol, e.g. AAPL, GOOG",
55 }
56 },
57 "required": ["symbol"],
58 },
59}
60# Tool input are same format with OpenAI tools
61openai_format_tools = [get_weather_api, search_api, get_stock]
62
63messages = [
64 {"role": "system", "content": "You are an expert in composing functions."},
65 {"role": "user", "content": "ขอราคาหุ้น Tasla (TLS) และ Amazon (AMZ) ?"},
66]
67
68inputs = tokenizer.apply_chat_template(
69 messages, tools=openai_format_tools, add_generation_prompt=True, return_tensors="pt"
70).to(model.device)
71
72outputs = model.generate(
73 inputs,
74 max_new_tokens=512,
75 do_sample=True,
76 temperature=0.7,
77 num_return_sequences=1,
78 eos_token_id=[tokenizer.eos_token_id, 128009],
79)
80response = outputs[0][inputs.shape[-1]:]
81
82print("Here Output:", tokenizer.decode(response, skip_special_tokens=True))
83
84
85# Decoding function utility
86def resolve_ast_by_type(value):
87 if isinstance(value, ast.Constant):
88 if value.value is Ellipsis:
89 output = "..."
90 else:
91 output = value.value
92 elif isinstance(value, ast.UnaryOp):
93 output = -value.operand.value
94 elif isinstance(value, ast.List):
95 output = [resolve_ast_by_type(v) for v in value.elts]
96 elif isinstance(value, ast.Dict):
97 output = {
98 resolve_ast_by_type(k): resolve_ast_by_type(v)
99 for k, v in zip(value.keys, value.values)
100 }
101 elif isinstance(
102 value, ast.NameConstant
103 ): # Added this condition to handle boolean values
104 output = value.value
105 elif isinstance(
106 value, ast.BinOp
107 ): # Added this condition to handle function calls as arguments
108 output = eval(ast.unparse(value))
109 elif isinstance(value, ast.Name):
110 output = value.id
111 elif isinstance(value, ast.Call):
112 if len(value.keywords) == 0:
113 output = ast.unparse(value)
114 else:
115 output = resolve_ast_call(value)
116 elif isinstance(value, ast.Tuple):
117 output = tuple(resolve_ast_by_type(v) for v in value.elts)
118 elif isinstance(value, ast.Lambda):
119 output = eval(ast.unparse(value.body[0].value))
120 elif isinstance(value, ast.Ellipsis):
121 output = "..."
122 elif isinstance(value, ast.Subscript):
123 try:
124 output = ast.unparse(value.body[0].value)
125 except:
126 output = ast.unparse(value.value) + "[" + ast.unparse(value.slice) + "]"
127 else:
128 raise Exception(f"Unsupported AST type: {type(value)}")
129 return output
130
131
132def resolve_ast_call(elem):
133 func_parts = []
134 func_part = elem.func
135 while isinstance(func_part, ast.Attribute):
136 func_parts.append(func_part.attr)
137 func_part = func_part.value
138 if isinstance(func_part, ast.Name):
139 func_parts.append(func_part.id)
140 func_name = ".".join(reversed(func_parts))
141 args_dict = {}
142 for arg in elem.keywords:
143 output = resolve_ast_by_type(arg.value)
144 args_dict[arg.arg] = output
145 return {func_name: args_dict}
146
147
148def ast_parse(input_str, language="Python"):
149 if language == "Python":
150 cleaned_input = input_str.strip("[]'")
151 parsed = ast.parse(cleaned_input, mode="eval")
152 extracted = []
153 if isinstance(parsed.body, ast.Call):
154 extracted.append(resolve_ast_call(parsed.body))
155 else:
156 for elem in parsed.body.elts:
157 assert isinstance(elem, ast.Call)
158 extracted.append(resolve_ast_call(elem))
159 return extracted
160 else:
161 raise NotImplementedError(f"Unsupported language: {language}")
162
163
164def parse_nested_value(value):
165 """
166 Parse a potentially nested value from the AST output.
167
168 Args:
169 value: The value to parse, which could be a nested dictionary, which includes another function call, or a simple value.
170
171 Returns:
172 str: A string representation of the value, handling nested function calls and nested dictionary function arguments.
173 """
174 if isinstance(value, dict):
175 # Check if the dictionary represents a function call (i.e., the value is another dictionary or complex structure)
176 if all(isinstance(v, dict) for v in value.values()):
177 func_name = list(value.keys())[0]
178 args = value[func_name]
179 args_str = ", ".join(
180 f"{k}={parse_nested_value(v)}" for k, v in args.items()
181 )
182 return f"{func_name}({args_str})"
183 else:
184 # If it's a simple dictionary, treat it as key-value pairs
185 return (
186 "{"
187 + ", ".join(f"'{k}': {parse_nested_value(v)}" for k, v in value.items())
188 + "}"
189 )
190 return repr(value)
191
192def default_decode_ast_prompting(result, language="Python"):
193 result = result.strip("`\n ")
194 if not result.startswith("["):
195 result = "[" + result
196 if not result.endswith("]"):
197 result = result + "]"
198 decoded_output = ast_parse(result, language)
199 return decoded_output
200
201fc_result = default_decode_ast_prompting(tokenizer.decode(response, skip_special_tokens=True))
202print(fc_result) # [{'Function': {'arguments': '{"symbol": "TLS"}', 'name': 'get_stock_price'}}, {'Function': {'arguments': '{"symbol": "AMZ"}', 'name': 'get_stock_price'}}]@misc{typhoon2,
title={Typhoon 2: A Family of Open Text and Multimodal Thai Large Language Models},
author={Kunat Pipatanakul and Potsawee Manakul and Natapong Nitarach and Warit Sirichotedumrong and Surapon Nonesung and Teetouch Jaknamon and Parinthapat Pengpun and Pittawat Taveekitworachai and Adisai Na-Thalang and Sittipong Sripaisarnmongkol and Krisanapong Jirayoot and Kasima Tharnpipitchai},
year={2024},
eprint={2412.13702},
archivePrefix={arXiv},
primaryClass={cs.CL},
url={https://arxiv.org/abs/2412.13702},
}