CoolFace
Modelpublic

vmal/3-digit-basic-calc

sourceHugging Facemitupdated 2mo agoView on Hugging Face
0likes20downloads
notebook.ipynb145 linesDownload Raw Back to root
1{2 "cells": [3  {4   "cell_type": "markdown",5   "metadata": {},6   "source": [7    "# \ud83e\uddee 3-digit-basic-calc \u2014 3-digit arithmetic with a 1.6M-parameter transformer\n",8    "\n",9    "A from-scratch transformer that does `+ \u2212 \u00d7 \u00f7` on 3-digit numbers by writing out\n",10    "the algorithm step by step. This notebook loads the model and runs it.\n",11    "\n",12    "Model: [`vmal/3-digit-basic-calc`](https://huggingface.co/vmal/3-digit-basic-calc)\n"13   ]14  },15  {16   "cell_type": "code",17   "metadata": {},18   "execution_count": null,19   "outputs": [],20   "source": [21    "%pip install -q transformers==5.3.0 torch safetensors\n"22   ]23  },24  {25   "cell_type": "markdown",26   "metadata": {},27   "source": [28    "## Load the model\n"29   ]30  },31  {32   "cell_type": "code",33   "metadata": {},34   "execution_count": null,35   "outputs": [],36   "source": [37    "from transformers import AutoModelForCausalLM, AutoTokenizer\n",38    "\n",39    "REPO = \"vmal/3-digit-basic-calc\"\n",40    "model = AutoModelForCausalLM.from_pretrained(REPO, trust_remote_code=True).eval()\n",41    "tok   = AutoTokenizer.from_pretrained(REPO, trust_remote_code=True)\n",42    "print(\"parameters:\", sum(p.numel() for p in model.parameters()))\n"43   ]44  },45  {46   "cell_type": "markdown",47   "metadata": {},48   "source": [49    "## Solve some problems\n",50    "\n",51    "`model.solve(tokenizer, expression)` returns the human-readable answer.\n"52   ]53  },54  {55   "cell_type": "code",56   "metadata": {},57   "execution_count": null,58   "outputs": [],59   "source": [60    "for e in [\"842/37\", \"213*145\", \"999*999\", \"-500+500\", \"3/31\", \"12/0\"]:\n",61    "    print(f\"{e:>10} = {model.solve(tok, e)}\")\n"62   ]63  },64  {65   "cell_type": "markdown",66   "metadata": {},67   "source": [68    "## See the model's reasoning\n",69    "\n",70    "Pass `return_trace=True` to get the raw scratchpad the model generates \u2014\n",71    "each `<step>`/`<qmul>`/`<rem>` is one local computation.\n"72   ]73  },74  {75   "cell_type": "code",76   "metadata": {},77   "execution_count": null,78   "outputs": [],79   "source": [80    "answer, trace = model.solve(tok, \"842/37\", return_trace=True)\n",81    "print(\"answer:\", answer)\n",82    "print()\n",83    "for c in ['<div>','<mul>','<add>','<sub>','<state>','<step>','<qmul>','<rem>','<col>','<ans>']:\n",84    "    trace = trace.replace(c, '\\n'+c+' ')\n",85    "print(trace.strip())\n"86   ]87  },88  {89   "cell_type": "markdown",90   "metadata": {},91   "source": [92    "## Quick in-range behavior check on random problems\n",93    "\n",94    "This small smoke test samples the supported operand range. It does not load\n",95    "the training prompts, so it should not be described as a leakage-controlled\n",96    "unseen benchmark; the card reports that benchmark separately.\n"97   ]98  },99  {100   "cell_type": "code",101   "metadata": {},102   "execution_count": null,103   "outputs": [],104   "source": [105    "import random\n",106    "random.seed(0)\n",107    "def truth(a, b, op):\n",108    "    if op == '+': return str(a + b)\n",109    "    if op == '-': return str(a - b)\n",110    "    if op == '*': return str(a * b)\n",111    "    if b == 0: return 'NAN'\n",112    "    # Exact integer round-half-up to three decimals (no float/banker's rounding).\n",113    "    denominator = abs(b)\n",114    "    scaled, remainder = divmod(abs(a) * 1000, denominator)\n",115    "    scaled += int(2 * remainder >= denominator)\n",116    "    integer, fraction = divmod(scaled, 1000)\n",117    "    magnitude = str(integer)\n",118    "    if fraction:\n",119    "        magnitude += '.' + f'{fraction:03d}'.rstrip('0')\n",120    "    negative = (a < 0) != (b < 0)\n",121    "    return '-' + magnitude if negative and scaled else magnitude\n",122    "good=n=0\n",123    "for _ in range(30):\n",124    "    a=random.randint(-999,999); b=random.randint(-999,999); op=random.choice('+-*/')\n",125    "    if op=='/' and b==0: b=7\n",126    "    got=model.solve(tok, f'{a}{op}{b}'); exp=truth(a,b,op)\n",127    "    good+= (got==exp); n+=1\n",128    "print(f'{good}/{n} correct on random in-range problems')\n"129   ]130  }131 ],132 "metadata": {133  "kernelspec": {134   "display_name": "Python 3",135   "language": "python",136   "name": "python3"137  },138  "language_info": {139   "name": "python"140  }141 },142 "nbformat": 4,143 "nbformat_minor": 5144}145