InteleionAI commited on
Commit
ba1c728
·
verified ·
1 Parent(s): 3be37ae

Upload folder using huggingface_hub

Browse files
Files changed (9) hide show
  1. config.json +1 -0
  2. fast.pkl +3 -0
  3. knn.npz +3 -0
  4. rep_G2b.json +43 -0
  5. rep_G2b.md +14 -0
  6. strat_infer.py +66 -0
  7. student_int8.onnx +3 -0
  8. tokenizer.json +0 -0
  9. tokenizer_config.json +24 -0
config.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"labels": ["Refund_not_showing_up", "activate_my_card", "age_limit", "apple_pay_or_google_pay", "atm_support", "automatic_top_up", "balance_not_updated_after_bank_transfer", "balance_not_updated_after_cheque_or_cash_deposit", "beneficiary_not_allowed", "cancel_transfer", "card_about_to_expire", "card_acceptance", "card_arrival", "card_delivery_estimate", "card_linking", "card_not_working", "card_payment_fee_charged", "card_payment_not_recognised", "card_payment_wrong_exchange_rate", "card_swallowed", "cash_withdrawal_charge", "cash_withdrawal_not_recognised", "change_pin", "compromised_card", "contactless_not_working", "country_support", "declined_card_payment", "declined_cash_withdrawal", "declined_transfer", "direct_debit_payment_not_recognised", "disposable_card_limits", "edit_personal_details", "exchange_charge", "exchange_rate", "exchange_via_app", "extra_charge_on_statement", "failed_transfer", "fiat_currency_support", "get_disposable_virtual_card", "get_physical_card", "getting_spare_card", "getting_virtual_card", "lost_or_stolen_card", "lost_or_stolen_phone", "order_physical_card", "passcode_forgotten", "pending_card_payment", "pending_cash_withdrawal", "pending_top_up", "pending_transfer", "pin_blocked", "receiving_money", "request_refund", "reverted_card_payment?", "supported_cards_and_currencies", "terminate_account", "top_up_by_bank_transfer_charge", "top_up_by_card_charge", "top_up_by_cash_or_cheque", "top_up_failed", "top_up_limits", "top_up_reverted", "topping_up_by_card", "transaction_charged_twice", "transfer_fee_charged", "transfer_into_account", "transfer_not_received_by_recipient", "transfer_timing", "unable_to_verify_identity", "verify_my_identity", "verify_source_of_funds", "verify_top_up", "virtual_card_not_working", "visa_or_mastercard", "why_verify_identity", "wrong_amount_of_cash_received", "wrong_exchange_rate_for_cash_withdrawal"], "tau": 0.813436990751346, "lam": 0.5, "mu": 0.0, "maxlen": 48, "knn_classes": 20}
fast.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3d693741676eac690a9036f1036dd4ccd2ebace44e486669872bbd2152eb7933
3
+ size 12300983
knn.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6015cdfabf08b32d822d2e8639d5afed68976a40fe2f009111706693e9070769
3
+ size 15445122
rep_G2b.json ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "accuracy_pct": 94.54545454545455,
3
+ "wilson95_pct": [
4
+ 93.68653351222973,
5
+ 95.29339334263855
6
+ ],
7
+ "n_test": 3080,
8
+ "coverage_pct": 100.0,
9
+ "latency_ms": {
10
+ "mean": 1.4180174440259738,
11
+ "p50": 0.24948399999999998,
12
+ "p95": 6.259047299999999,
13
+ "p99": 10.405148300000006,
14
+ "per_pass_mean_min": 1.3956335178571428,
15
+ "per_pass_mean_median": 1.4149175311688313,
16
+ "per_pass_mean_max": 1.438470613961039
17
+ },
18
+ "tiers": {
19
+ "fast": {
20
+ "share_pct": 77.30519480519482,
21
+ "mean_ms": 0.2452698942461151,
22
+ "p95_ms": 0.4368241999999999
23
+ },
24
+ "student": {
25
+ "share_pct": 22.694805194805195,
26
+ "mean_ms": 5.412741215164521,
27
+ "p95_ms": 10.006944799999998
28
+ }
29
+ },
30
+ "env": {
31
+ "cpu": "Intel(R) Xeon(R) CPU @ 2.00GHz",
32
+ "logical_cpus": 4,
33
+ "threads": 1,
34
+ "python": "3.13.15",
35
+ "numpy": "2.1.3",
36
+ "onnxruntime": "1.31.1"
37
+ },
38
+ "package_mb": 51.451753,
39
+ "load_s": 0.22228096300023026,
40
+ "reps": 5,
41
+ "seed": 0,
42
+ "gc_paused_in_timed_loop": true
43
+ }
rep_G2b.md ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ | Metric | Value |
2
+ |---|---|
3
+ | Test set | Banking77 official test split, 3080 queries, all answered (coverage 100.0%) |
4
+ | Accuracy | 94.55% (Wilson 95% interval 93.69-95.29) |
5
+ | Mean latency | 1.42 ms (per-pass means 1.40-1.44, 5 passes) |
6
+ | p50 / p95 / p99 | 0.25 / 6.26 / 10.41 ms |
7
+ | Tier 1 (tf-idf) | 77.3% of queries, mean 0.25 ms |
8
+ | Tier 2 (int8 MiniLM-L6 + kNN) | 22.7% of queries, mean 5.41 ms |
9
+ | Hardware | Intel(R) Xeon(R) CPU @ 2.00GHz, 4 logical CPUs visible, 1 thread used |
10
+ | Software | Python 3.13.15, onnxruntime 1.31.1, numpy 2.1.3 |
11
+ | Package | 51 MB, loads in 0.2 s |
12
+
13
+ Latency is wall-clock per single query (tokenizer, tf-idf, gate, ONNX int8 student, kNN, label lookup), one query at a time, 1 thread, warm process,
14
+ GC paused in the timed loop; 5 passes over the test set in different random orders. Excludes process start-up. Shared cloud CPUs vary by session; compare runs from the same session.
strat_infer.py ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json, os, pickle, re, numpy as np, onnxruntime as ort
2
+ from tokenizers import Tokenizer
3
+ _TP = re.compile(r"(?u)\b\w\w+\b")
4
+ class Strat:
5
+ """strat (fast kNN): tier-1 tf-idf, escalating to tier-2 int8 student + class-restricted kNN memory. CPU, 1 thread."""
6
+ def __init__(s, path, threads=1):
7
+ c = json.load(open(os.path.join(path, "config.json"))); s.c = c; s.labels = c["labels"]; C = len(s.labels)
8
+ s.wv, s.wi, s.cv, s.ci, s.cT, s.b = pickle.load(open(os.path.join(path, "fast.pkl"), "rb")); s.off = len(s.wv)
9
+ so = ort.SessionOptions(); so.intra_op_num_threads = threads; so.inter_op_num_threads = 1
10
+ s.sess = ort.InferenceSession(os.path.join(path, "student_int8.onnx"), so, providers=["CPUExecutionProvider"])
11
+ s.bt = Tokenizer.from_file(os.path.join(path, "tokenizer.json")); s.bt.enable_truncation(c["maxlen"]); s.bt.no_padding()
12
+ k = np.load(os.path.join(path, "knn.npz")); E, y = k["E"], k["y"]
13
+ o = np.argsort(y, kind="stable"); s.Ei = np.ascontiguousarray(E[o]); s.yi = y[o].astype(np.int64) # sorted by class
14
+ s.coff = np.concatenate([[0], np.cumsum(np.bincount(s.yi, minlength=C))]).astype(np.int64)
15
+ s.M = int(c.get("knn_classes", 20)); s.nl = C
16
+ def _tf(s, terms, vocab, idf, off):
17
+ cnt = {}
18
+ for t in terms:
19
+ j = vocab.get(t)
20
+ if j is not None: cnt[j] = cnt.get(j, 0) + 1
21
+ if not cnt: return None
22
+ idx = np.fromiter(cnt.keys(), dtype=np.int64, count=len(cnt)); tf = np.fromiter(cnt.values(), dtype=np.float32, count=len(cnt))
23
+ v = (1.0 + np.log(tf)) * idf[idx]; n = np.sqrt((v * v).sum())
24
+ return idx + off, (v / n if n > 0 else v)
25
+ def feat(s, text):
26
+ t = text.lower(); w = _TP.findall(t)
27
+ a = s._tf(w + [w[i] + " " + w[i + 1] for i in range(len(w) - 1)], s.wv, s.wi, 0)
28
+ cg = []
29
+ for wd in t.split():
30
+ wd = " " + wd + " "; L = len(wd)
31
+ for n in range(2, 6):
32
+ o = 0; cg.append(wd[o:o + n])
33
+ while o + n < L:
34
+ o += 1; cg.append(wd[o:o + n])
35
+ if o == 0: break
36
+ b = s._tf(cg, s.cv, s.ci, s.off)
37
+ ps = [x for x in (a, b) if x is not None]
38
+ if not ps: return np.zeros(0, np.int64), np.zeros(0, np.float32)
39
+ return np.concatenate([p[0] for p in ps]), np.concatenate([p[1] for p in ps]).astype(np.float32)
40
+ def fast_p(s, text):
41
+ idx, val = s.feat(text)
42
+ z = val @ s.cT[idx] + s.b
43
+ z = z - z.max(); p = np.exp(z); return p / p.sum()
44
+ def _knn(s, e, p, p_tf):
45
+ if s.M <= 0 or s.M >= s.nl:
46
+ sim = s.Ei @ e; lab = s.yi
47
+ else:
48
+ cand = np.argpartition(-p, s.M)[:s.M]
49
+ if p_tf is not None: cand = np.union1d(cand, np.argpartition(-p_tf, 4)[:4])
50
+ co = s.coff; sims = [s.Ei[co[c]:co[c + 1]] @ e for c in cand]
51
+ sim = np.concatenate(sims); lab = np.concatenate([s.yi[co[c]:co[c + 1]] for c in cand])
52
+ top = np.argpartition(-sim, 10)[:10]; w = np.exp((sim[top] - sim[top].max()) / 0.05)
53
+ pk = np.bincount(lab[top], weights=w, minlength=s.nl); return pk / pk.sum()
54
+ def student_p(s, text, p_tf=None):
55
+ ids = np.array([s.bt.encode(text).ids], dtype=np.int64)
56
+ lg, e = s.sess.run(None, {"input_ids": ids, "attention_mask": np.ones_like(ids)})
57
+ z = lg[0] - lg[0].max(); p = np.exp(z); p /= p.sum()
58
+ lam = s.c["lam"]
59
+ if lam > 0: p = (1 - lam) * p + lam * s._knn(e[0], p, p_tf)
60
+ mu = s.c.get("mu", 0.0)
61
+ if mu > 0 and p_tf is not None: p = (1 - mu) * p + mu * p_tf
62
+ return p
63
+ def predict_one(s, text):
64
+ p = s.fast_p(text)
65
+ if p.max() >= s.c["tau"]: return s.labels[int(p.argmax())], "fast"
66
+ return s.labels[int(s.student_p(text, p).argmax())], "student"
student_int8.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:724ff63982904dbfc6e763e8643d7f575d63c1343bbb8f91550667aa79ce338f
3
+ size 22983507
tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
tokenizer_config.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "backend": "tokenizers",
3
+ "cls_token": "[CLS]",
4
+ "do_basic_tokenize": true,
5
+ "do_lower_case": true,
6
+ "is_local": false,
7
+ "local_files_only": false,
8
+ "mask_token": "[MASK]",
9
+ "max_length": 128,
10
+ "model_max_length": 512,
11
+ "never_split": null,
12
+ "pad_to_multiple_of": null,
13
+ "pad_token": "[PAD]",
14
+ "pad_token_type_id": 0,
15
+ "padding_side": "right",
16
+ "sep_token": "[SEP]",
17
+ "stride": 0,
18
+ "strip_accents": null,
19
+ "tokenize_chinese_chars": true,
20
+ "tokenizer_class": "BertTokenizer",
21
+ "truncation_side": "right",
22
+ "truncation_strategy": "longest_first",
23
+ "unk_token": "[UNK]"
24
+ }