Ahmetemiiii2 commited on
Commit
c3b0e8f
·
verified ·
1 Parent(s): 718d1a1

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +81 -1
README.md CHANGED
@@ -67,7 +67,87 @@ Kullanıcı: {message}
67
  Töz: {response}<|endoftext|>
68
  ```
69
 
70
- ## Training
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
 
72
  ### Pre-training
73
  Fineweb-2 + wiki filtered, trained 15B token
 
67
  Töz: {response}<|endoftext|>
68
  ```
69
 
70
+ ## Tool use: calculator
71
+
72
+ Töz-1.5 does not compute arithmetic itself. It writes the expression inside `<hesap>…</hesap>` ("hesap" = calculation), an external calculator evaluates it, and the result is inserted inside `<sonuc>…</sonuc>` ("sonuç" = result). The model then continues and writes the final answer:
73
+
74
+ ```
75
+ Kullanıcı: 25*4-10 kaç eder peki?
76
+ Töz: Hesaplayalım: <hesap>25*4-10</hesap>
77
+ <sonuc>90</sonuc>
78
+ Sonuç: 90.
79
+ ```
80
+
81
+ How it works:
82
+
83
+ 1. Generate until the model writes `</hesap>`, then stop.
84
+ 2. Evaluate the expression between `<hesap>` and `</hesap>`.
85
+ 3. Append `\n<sonuc>{result}</sonuc>\n` to the text and continue generating.
86
+
87
+ If you skip the tool loop, the model may fill in `<sonuc>` on its own, and that value is not reliable, especially for large numbers. Always run the calculator.
88
+
89
+ ```python
90
+ import ast, operator
91
+ from fractions import Fraction
92
+ import torch
93
+ from transformers import AutoTokenizer, AutoModelForCausalLM
94
+
95
+ model_id = "TozAI/Toz-1.5"
96
+ tok = AutoTokenizer.from_pretrained(model_id)
97
+ model = AutoModelForCausalLM.from_pretrained(model_id, dtype=torch.float16) # use torch.float32 on CPU
98
+
99
+ OPS = {ast.Add: operator.add, ast.Sub: operator.sub, ast.Mult: operator.mul,
100
+ ast.Div: operator.truediv, ast.Mod: operator.mod, ast.Pow: operator.pow,
101
+ ast.USub: operator.neg, ast.UAdd: operator.pos}
102
+
103
+ def calculate(expr: str) -> str:
104
+ """Safe calculator: numbers, + - * / % ** and parentheses only. No eval()."""
105
+ expr = expr.replace("×", "*").replace("÷", "/").replace("^", "**")
106
+ def ev(n):
107
+ if isinstance(n, ast.Expression):
108
+ return ev(n.body)
109
+ if isinstance(n, ast.Constant) and isinstance(n.value, (int, float)):
110
+ return Fraction(str(n.value))
111
+ if isinstance(n, ast.BinOp) and type(n.op) in OPS:
112
+ a, b = ev(n.left), ev(n.right)
113
+ if isinstance(n.op, ast.Pow):
114
+ if b.denominator != 1 or abs(b) > 1000:
115
+ raise ValueError("unsupported exponent")
116
+ b = int(b)
117
+ return OPS[type(n.op)](a, b)
118
+ if isinstance(n, ast.UnaryOp) and type(n.op) in OPS:
119
+ return OPS[type(n.op)](ev(n.operand))
120
+ raise ValueError("unsupported expression")
121
+ r = ev(ast.parse(expr, mode="eval"))
122
+ return str(r.numerator) if r.denominator == 1 else f"{float(r):.10g}"
123
+
124
+ def chat(question: str, max_new_tokens: int = 256, max_calls: int = 5) -> str:
125
+ text = tok.apply_chat_template([{"role": "user", "content": question}],
126
+ add_generation_prompt=True, tokenize=False)
127
+ start = len(text)
128
+ for _ in range(max_calls + 1):
129
+ ids = tok(text, return_tensors="pt", add_special_tokens=False)
130
+ out = model.generate(**ids, max_new_tokens=max_new_tokens, do_sample=False,
131
+ stop_strings=["</hesap>"], tokenizer=tok)
132
+ new = tok.decode(out[0][ids["input_ids"].shape[1]:], skip_special_tokens=True)
133
+ text += new
134
+ if not new.rstrip().endswith("</hesap>"):
135
+ break
136
+ expr = text.rsplit("<hesap>", 1)[1].rsplit("</hesap>", 1)[0]
137
+ try:
138
+ result = calculate(expr)
139
+ except Exception:
140
+ result = "hata" # "error"
141
+ text += f"\n<sonuc>{result}</sonuc>\n"
142
+ return text[start:].strip()
143
+
144
+ print(chat("12*7 kaç eder?"))
145
+ # Hesaplayalım: <hesap>12*7</hesap>
146
+ # <sonuc>84</sonuc>
147
+ # Sonuç: 84.
148
+ ```
149
+
150
+ The calculator uses exact integer and fraction arithmetic, so large numbers are not rounded. It never calls `eval()`. Only numbers, the four operations, `%`, `**` and parentheses are accepted.
151
 
152
  ### Pre-training
153
  Fineweb-2 + wiki filtered, trained 15B token