gpu-sankhya

A small char-level CNN that extracts Indian informal number/currency shorthand -- Hinglish (romanised Hindi), Devanagari Hindi, and Indian-English amount phrases like sava lakh, dedh crore, डेढ़ लाख, सवा करोड़, 2.5L, 20k, 2-3 lakh -- from free text, and turns each match into a clean numeric value via a deterministic arithmetic core (the model never predicts the value directly).

This model card describes weights version v0.3.4 (arch v2).

Architecture

A dilated/residual char-CNN over per-character embeddings:

  • embedding dim: 16
  • conv channels: 48
  • 5 conv layers:
    1. kernel 5, dilation 1, residual no
    2. kernel 3, dilation 1, residual yes
    3. kernel 3, dilation 2, residual yes
    4. kernel 3, dilation 4, residual yes
    5. kernel 3, dilation 8, residual yes
  • vocab: 115 characters (union of the hi_latn and hi_deva packs)
  • output classes: 120 (BIO span tag + semantic token class)
  • parameters: 39,595

A deterministic arithmetic core (not part of this model) then evaluates the decoded token sequence into a value: prefix semantics (sava = x1.25, dedh = x1.5, paune = subtract 1/4 from the next cardinal, ...), additive combination of descending units, multiplicative combination of ascending units, and range handling.

Files

file size
charset.json 930 bytes
classes.json 1,571 bytes
gold_metrics_json_float32.json 4,572 bytes
gold_metrics_json_int8.json 4,572 bytes
gold_metrics_torch.json 4,572 bytes
kaggle_metrics.json 16,439 bytes
matrix.md 739 bytes
sankhya.onnx 161,024 bytes
sankhya.pt 167,990 bytes
sankhya.weights.int8.json 59,007 bytes
sankhya.weights.json 397,834 bytes
  • sankhya.pt -- torch checkpoint (vocab, classes, arch, channels, state_dict)
  • sankhya.onnx -- ONNX graph, for interop/inspection
  • sankhya.weights.json -- float32 weights, human-readable JSON
  • sankhya.weights.int8.json -- int8-quantized weights (what the npm package and this card's accuracy numbers use)
  • charset.json, classes.json -- standalone vocab/class tables
  • gold_metrics_*.json -- per-file + combined gold evaluation (torch, float32 JSON, int8 JSON)
  • matrix.md, kaggle_metrics.json -- training/sweep provenance from the Kaggle GPU run that produced this checkpoint

Accuracy

Evaluated with the int8-quantized weights (what ships in the npm package) against two hand-written gold sets (gold_hi_latn.jsonl, gold_hi_deva.jsonl -- see the dataset card):

gold set examples spans value_acc precision recall F1
gold.jsonl 225 197 0.9543 0.9497 0.9594 0.9545
gold_deva.jsonl 185 154 0.9740 0.9805 0.9805 0.9805
combined 410 351 0.9630 0.9632 0.9687 0.9659

Negatives (zero-gold-span examples): 75, false positives: 0 (0.00%).

Per-category value accuracy (combined):

category spans value_acc
digits 92 0.9674
words 259 0.9614
prefix 81 0.9630
range 27 0.8889
currency 48 1.0000
multi_unit 24 0.9167
symbol_unit 33 1.0000
mixed_script 2 1.0000
long 12 0.6667

Usage

JavaScript (recommended -- ships this model quantized, no download)

import { parse } from "gpu-sankhya";

parse("sava lakh");
// [{ span: "sava lakh", value: 125000, unit: "lakh", ... }]

Python (numpy reference forward pass)

import numpy as np
from sankhya import np_infer, decode, core, charset
from sankhya.train import build_char_to_id

weights_json = json.load(open("sankhya.weights.int8.json"))
weights = np_infer.load_weights_int8_json(weights_json)
char_to_id = build_char_to_id(weights_json["charset"])
unk = char_to_id.get("<unk>", 1)

text = charset.normalize_text("sava lakh")
ids = np_infer.pad_ids([char_to_id.get(c, unk) for c in text])
bio_logits, cls_logits = np_infer.forward(weights, np.array(ids))
n = len(text)
bio_pred = bio_logits[:n].argmax(-1).tolist()
cls_pred = cls_logits[:n].argmax(-1).tolist()
bio_probs = np_infer.softmax(bio_logits[:n]).tolist()

spans = decode.decode_spans(text, bio_pred, cls_pred, bio_probs=bio_probs)
for span in spans:
    result = core.evaluate(span["tokens"])
    print(text[span["start"]:span["end"]], result.value)

See python/README.md in the source repo for the full training/export pipeline and sankhya.eval_gold for a ready-made evaluation CLI.

Training

Trained 20 epochs on 200,000 synthetic examples generated from both the hi_latn (romanised Hindi) and hi_deva (Devanagari Hindi) grammar packs, mixed 0.55/0.45 with a 10% cross-pack share, plus out-of-vocab "unk noise" augmentation (emoji, CJK, Cyrillic, other symbols inserted as O-labelled context) so the <unk> embedding actually gets gradient signal. Batch size 128, lr 3e-3. Architecture and channel count (v2, 48 channels) were chosen by a config/seed sweep, picking the config with the highest mean int8 combined gold value_acc across >= 3 seeds (seed spread is +/-1-2 points), then the seed by val accuracy within a 0.005 tie band, then higher int8 combined gold F1, then lower negatives false-positive rate. Full recipe, sweep evidence, and reproduction commands: python/README.md in the source repo.

Limitations

  • JavaScript string indices count UTF-16 code units, so astral characters (e.g. some emoji) occupy 2 code units -- span offsets from the JS runtime account for this, but consumers indexing raw strings themselves should be aware of it.
  • The model occasionally produces spurious spans on unfamiliar words near number-ish context (a measured trade-off from the out-of-vocab noise training -- see Accuracy above).
  • Long multi-term/mixed-numeral constructs and multi-number range phrases ("तीस पैंतीस हज़ार", "three n half lakh") are the weakest category (long/range value_acc above).
  • Scoped to Indian languages: currently Hinglish and Devanagari Hindi only; other Indian languages are planned (see the source repo's roadmap).
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Dataset used to train athrvk/gpu-sankhya

Space using athrvk/gpu-sankhya 1