2026-07-01 — #825: the retrain that regressed, and the $0 tokenizer splice that fixed it
Day shift. The brief was simple: merge the night's PRs, then spend a generous GPU budget on #825 — the Czech/Polish diacriticdiacriticAn accent mark that modifies a letter (é, ñ, ç). Address normalization must fold diacritics for matching without discarding the information a user typed. problem where addresses were geocodinggeocodingThe process of converting an address into geographic coordinates (latitude and longitude). Mailwoman geocodes in a multi-tier cascade: exact address-point match → street interpolation → locality centroid. Each tier is progressively coarser but more widely available. to the wrong citylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy.. We spent the budget, the retrain failed, and the fix turned out to need no GPU trainingtrainingThe process of adjusting a model's parameters so its predictions match labeled examples, by repeatedly measuring error and nudging the weights to reduce it. Distinct from inference, when the trained model is run on new input. at all — a tokenizertokenizerThe component that converts a raw address string into a sequence of numeric token IDs the model can process. Mailwoman's tokenizer is a SentencePiece unigram model trained specifically on postal addresses. splice and an embeddingembeddingA vector of numbers representing a token (or other item) so that similar items sit near each other in vector space. The first thing the model does is turn each token into an embedding. average. The interesting part is why.
What we set out to do
#825 was filed as a retrain: add an OpenAddressesOpenAddresses (OA). A global open aggregation of address points collected from many official sources. A primary source of component-supervised training data outside proprietary registries. Slavic-diacriticdiacriticAn accent mark that modifies a letter (é, ñ, ç). Address normalization must fold diacritics for matching without discarding the information a user typed. shardshardA partial output file of the corpus build, written in Parquet format. The training pipeline streams shards row by row. so the modelneural classifierThe machine learning model at the core of Mailwoman's parser — a transformer encoder (~30M parameters) trained from scratch to do BIO token classification over addresses. It learns the 'grammar' of address formats; the gazetteer supplies the 'atlas.' stops tagging
č ř ž ą ł tokenstokenOne word or subword in the tokenized input. For the neural classifier, tokens come from SentencePiece (subword units); for the rule classifiers, tokens are whitespace- and punctuation-separated words. as O. The hypothesis was that Czech/Polish streetstreetThe named linear feature along which house numbers are ordered. Decomposes into a name plus street affixes; one of the Tier 2 fine labels. and localitylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy. names were fragmenting
because the modelneural classifierThe machine learning model at the core of Mailwoman's parser — a transformer encoder (~30M parameters) trained from scratch to do BIO token classification over addresses. It learns the 'grammar' of address formats; the gazetteer supplies the 'atlas.' had never seen them with house-number/streetstreetThe named linear feature along which house numbers are ordered. Decomposes into a name plus street affixes; one of the Tier 2 fine labels. context — a trainingtrainingThe process of adjusting a model's parameters so its predictions match labeled examples, by repeatedly measuring error and nudging the weights to reduce it. Distinct from inference, when the trained model is run on new input.-data gap.
The arc
We built the ship candidate carefully — and caught a trap doing it. The obvious move was to grade the
running probe (v1.9.3-slavic-diacritic). But that recipe was copied from v1.9.2-multilocale-au (v4.14.0),
which predates the #723 anchor-absorption fix. Grading it against v4.15.0 would have confounded the Slavic
shardshardA partial output file of the corpus build, written in Parquet format. The training pipeline streams shards row by row. with a reverted #723 — and #723 is coordinate-invisible, so the coord gate would never have caught it.
So we forked a clean candidate, v196-slavic-anchor = v4.15.0's recipe verbatim + the one new shardshardA partial output file of the corpus build, written in Parquet format. The training pipeline streams shards row by row., off
the v4.15.0 corpuscorpusThe BIO-labeled training data used to train Mailwoman's neural classifier. Assembled from real sources (OpenAddresses, National Address Database) and synthetic shards (boundary stress, order variants, negative space). Managed by @mailwoman/corpus. so it keeps #723. One variable. (Lesson banked: a shardshardA partial output file of the corpus build, written in Parquet format. The training pipeline streams shards row by row. recipe copied from vN-1 silently
inherits vN-1's bugs.)
The mid-train read (40k) said US was untouched and CZ/PL was flat. US coord p50 diff −0.002km, CI [−0.02, 0]. CZ/PL wrong-citylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy. rate unchanged. The shardshardA partial output file of the corpus build, written in Parquet format. The training pipeline streams shards row by row. was proving genuinely US-safe but not moving the coordinate.
The coveragecoverageThe fraction of a population or region for which a data source has real, non-placeholder entries — e.g. 47% rooftop coverage on Texas addresses. Distinct from accuracy on the rows that are present. detour, and the eyeball that overturned our own aggregate. The operator asked us to scope
whether CZ/PL was coveragecoverageThe fraction of a population or region for which a data source has real, non-placeholder entries — e.g. 47% rooftop coverage on Texas addresses. Distinct from accuracy on the rows that are present.-bound before deciding. The resolved-p50 aggregate (CZ 5.24km) looked like "right
citylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy., just coarse — needs rooftop datasitus dataA dataset of exact address-point coordinates (rooftop-level). Mailwoman's geocoder uses a national situs layer (124.9M US points built from state address-point sources) as the highest-precision tier of the geocode cascade.." The eyeball said otherwise: ~40% of Czech addresses were landing in
the wrong citylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy. entirely (80–280km off), because the diacriticdiacriticAn accent mark that modifies a letter (é, ñ, ç). Address normalization must fold diacritics for matching without discarding the information a user typed. parseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates. was broken — Vysoká read as
Vysok, Čistá as istá, localities truncated. The p50 had hidden a bimodal distribution. This is
verify-before-verdict firing on our own summary statistic: the aggregate wasn't the verdict, the evidence
was. CZ/PL was parseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates.-bound, not coveragecoverageThe fraction of a population or region for which a data source has real, non-placeholder entries — e.g. 47% rooftop coverage on Texas addresses. Distinct from accuracy on the rows that are present.-bound, and coveragecoverageThe fraction of a population or region for which a data source has real, non-placeholder entries — e.g. 47% rooftop coverage on Texas addresses. Distinct from accuracy on the rows that are present. can't touch a wrong-citylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy. row.
The research said we weren't alone. A tokenizertokenizerThe component that converts a raw address string into a sequence of numeric token IDs the model can process. Mailwoman's tokenizer is a SentencePiece unigram model trained specifically on postal addresses. probe confirmed the mechanism: the 48k SentencePieceSentencePieceA language-independent subword tokenizer that splits text into pieces using a unigram language model. Mailwoman uses a SentencePiece tokenizer with a 48,000-token vocabulary and byte-fallback, trained on address data rather than general text. vocabvocabularyThe fixed set of tokens a tokenizer can produce. Mailwoman's SentencePiece vocabulary is tens of thousands of subword pieces, with byte fallback for anything outside it. has the diacriticdiacriticAn accent mark that modifies a letter (é, ñ, ç). Address normalization must fold diacritics for matching without discarding the information a user typed. characters but no multi-char subwords containing them, so every diacriticdiacriticAn accent mark that modifies a letter (é, ñ, ç). Address normalization must fold diacritics for matching without discarding the information a user typed. isolates its own piece — CZ localities at 3.3× English fertilityfertilityHow many tokenizer pieces it takes to spell a word: fertility 1 means whole words survive tokenization, fertility 3 means they arrive in fragments. High fertility hurts sequence labeling directly — the model has to reassemble a word before it can label it, and fragment boundaries are where labels break. Mailwoman measured this on French street names: accented words splitting at the accent ('René' → '▁Ren' + 'é') caused real geocoding misses, and lowering French fertility was worth a tokenizer revision plus a retrain.. This is the documented "tokenizertokenizerThe component that converts a raw address string into a sequence of numeric token IDs the model can process. Mailwoman's tokenizer is a SentencePiece unigram model trained specifically on postal addresses. fertilityfertilityHow many tokenizer pieces it takes to spell a word: fertility 1 means whole words survive tokenization, fertility 3 means they arrive in fragments. High fertility hurts sequence labeling directly — the model has to reassemble a word before it can label it, and fragment boundaries are where labels break. Mailwoman measured this on French street names: accented words splitting at the accent ('René' → '▁Ren' + 'é') caused real geocoding misses, and lowering French fertility was worth a tokenizer revision plus a retrain. tax." Four parallel SOTA agents + a DeepSeek consult mapped the fix space: vocabularyvocabularyThe fixed set of tokens a tokenizer can produce. Mailwoman's SentencePiece vocabulary is tens of thousands of subword pieces, with byte fallback for anything outside it. expansion (byte-identical English by construction), byte/char-level modelsneural classifierThe machine learning model at the core of Mailwoman's parser — a transformer encoder (~30M parameters) trained from scratch to do BIO token classification over addresses. It learns the 'grammar' of address formats; the gazetteer supplies the 'atlas.' (universal but latency-heavy), and a CharCNN front-end (cheap + universal). The fix was tokenizertokenizerThe component that converts a raw address string into a sequence of numeric token IDs the model can process. Mailwoman's tokenizer is a SentencePiece unigram model trained specifically on postal addresses.-side; the shardshardA partial output file of the corpus build, written in Parquet format. The training pipeline streams shards row by row. was the wrong lever.
The 80k gate confirmed it — and then some. v196 at full convergence: US held (p50 3.31, zero dilution), PL flat, but CZ regressed — resolved-p50 5.24 → 82.89km, wrong-citylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy. 44 → 58%. At 40k CZ was flat; the extra 40k steps at constant LR overfit the shardshardA partial output file of the corpus build, written in Parquet format. The training pipeline streams shards row by row. and broke the Czech parsesaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates.. NO-PROMOTE. The retrain didn't just fail to help — at scale it did harm. We only know because we graded the assembled coordinatecoord metricThe primary evaluation metric: distance from the resolved coordinate to the true address point. Measured at percentiles (p50, p90) and as 'within X meters.' Prevents the label-F1 trap where a model scores higher on token labels but geocodes worse.; on labelcomponent tagOne of the 33 labels in Mailwoman's address schema — street, locality, region, postcode, house_number, unit, po_box, country, venue, intersection, and others. Each parsed span carries exactly one component tag.-F1 the content-gap went 100→17% and the modelneural classifierThe machine learning model at the core of Mailwoman's parser — a transformer encoder (~30M parameters) trained from scratch to do BIO token classification over addresses. It learns the 'grammar' of address formats; the gazetteer supplies the 'atlas.' looked fixed.
The tokenizertokenizerThe component that converts a raw address string into a sequence of numeric token IDs the model can process. Mailwoman's tokenizer is a SentencePiece unigram model trained specifically on postal addresses. splice fixed it at nearly zero cost. We trained a Czech/Polish SentencePieceSentencePieceA language-independent subword tokenizer that splits text into pieces using a unigram language model. Mailwoman uses a SentencePiece tokenizer with a 48,000-token vocabulary and byte-fallback, trained on address data rather than general text. unigram, kept only the piecesECE (Expected Calibration Error). A metric that measures how well a model's confidence scores align with its actual accuracy. Lower is better. Mailwoman's held-out ECE drops from 0.067 (raw) to 0.0035 (calibrated). containing a non-ASCII codepoint, and appended them to the 48k vocabvocabularyThe fixed set of tokens a tokenizer can produce. Mailwoman's SentencePiece vocabulary is tens of thousands of subword pieces, with byte fallback for anything outside it.. Because a diacriticdiacriticAn accent mark that modifies a letter (é, ñ, ç). Address normalization must fold diacritics for matching without discarding the information a user typed. piece can't match any spanspanA contiguous range of characters or tokens in the input string, tagged with an address component type (street, locality, postcode, etc.). Parsed addresses are represented as collections of spans, possibly nested in a tree. of an English string, English tokenizes byte-identically by construction — we verified 0/2000 US rows changed. Mean-init the 10,582 new embeddingembeddingA vector of numbers representing a token (or other item) so that similar items sit near each other in vector space. The first thing the model does is turn each token into an embedding. rows from their old-tokenizertokenizerThe component that converts a raw address string into a sequence of numeric token IDs the model can process. Mailwoman's tokenizer is a SentencePiece unigram model trained specifically on postal addresses. constituents, a 2k-step fine-tune, and grade with the spliced tokenizertokenizerThe component that converts a raw address string into a sequence of numeric token IDs the model can process. Mailwoman's tokenizer is a SentencePiece unigram model trained specifically on postal addresses..
The numbers
Same golden setsgolden setA hand-labeled evaluation dataset of US, French, and adversarial addresses used as ground truth for evals., same grader; the B columns are graded with the spliced tokenizertokenizerThe component that converts a raw address string into a sequence of numeric token IDs the model can process. Mailwoman's tokenizer is a SentencePiece unigram model trained specifically on postal addresses..
| metric | baseline v4.15.0 | v196 retrain (80k) | B splice + 2k FT | B splice, mean-init only ($0) |
|---|---|---|---|---|
| US-2k coord p50 | 3.31 km | 3.31 (flat) | 3.31 (diff 0) | 3.31 (diff 0, CI [0,0]) |
| US regionregionThe first-level administrative subdivision of a country — a US state, a French region, a province. The component between country and locality.-match | 0.999 | 0.999 | 0.999 | 0.999 |
| CZ resolved-p50 | 5.24 km | 82.89 ✗ | 3.75 | 3.52 |
| CZ wrong-citylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy. (>20km) | 44% | 58% ✗ | 30% | 28% |
| PL resolved-p50 | 2.37 km | 2.37 | 1.53 | 1.53 |
| PL wrong-citylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy. | 30% | 30% | 11% | 11% |
Tokenization, before → after splice: Vysoká 4→1 piece, Grudziądz 6→1, Świętokrzyska 9→1, Čistá 5→2.
The eyeball confirmed the mechanism end-to-end — Fr. Černého, Střížovice, Březová nad Svitavou now parseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates.
as whole names where the baseline truncated them to Fr, St, B.
The ablation is the punchline: the fine-tune was unnecessary. We ran the splice + mean-init modelneural classifierThe machine learning model at the core of Mailwoman's parser — a transformer encoder (~30M parameters) trained from scratch to do BIO token classification over addresses. It learns the 'grammar' of address formats; the gazetteer supplies the 'atlas.' without any fine-tune and it matches or beats the fine-tuned version on every metric (CZ wrong-citylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy. 28% vs the fine-tune's 30%; PL and US identical). The 2k fine-tune not only added nothing — it began drifting toward the same overfit that killed v196. So the fix is a tokenizertokenizerThe component that converts a raw address string into a sequence of numeric token IDs the model can process. Mailwoman's tokenizer is a SentencePiece unigram model trained specifically on postal addresses. splice plus an embeddingembeddingA vector of numbers representing a token (or other item) so that similar items sit near each other in vector space. The first thing the model does is turn each token into an embedding. average: no GPU trainingtrainingThe process of adjusting a model's parameters so its predictions match labeled examples, by repeatedly measuring error and nudging the weights to reduce it. Distinct from inference, when the trained model is run on new input.. And because it leaves v4.15.0's encoderencoderThe part of a transformer that turns input tokens into contextualized vector representations. Mailwoman's classifier is a small encoder-only transformer (~30M parameters). byte-for-byte untouched, US identity is a guarantee (encoderencoderThe part of a transformer that turns input tokens into contextualized vector representations. Mailwoman's classifier is a small encoder-only transformer (~30M parameters). unchanged + English input_ids unchanged → identical logitslogitA raw, unnormalized per-label score the model outputs before softmax. Priors and biases are added in logit space, then softmax turns logits into probabilities.), not an observation — the freeze-encoderencoderThe part of a transformer that turns input tokens into contextualized vector representations. Mailwoman's classifier is a small encoder-only transformer (~30M parameters). variant we were going to build is what the mean-init already is.
Every gate passes: US non-inferiority (byte-identical), CZ improvement (p50 −1.70, CI wholly negative, wrong-citylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy. 44→28), PL improvement (p50 −0.85, wrong-citylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy. 30→11), functional eyeball (no over-tagging).
What worked
- Grading the coordinate, not labelcomponent tagOne of the 33 labels in Mailwoman's address schema — street, locality, region, postcode, house_number, unit, po_box, country, venue, intersection, and others. Each parsed span carries exactly one component tag.-F1. This is the whole story. The retrain's content-gap win (100→17) was real and would have shipped a coordinate regression. The wrong-citylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy. decomposition (tight / coarse / wrong-citylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy. buckets) is the honest metric for these localeslocaleThe combination of language and country an address comes from. en-US and fr-FR are the locales Mailwoman ships weights for. and should be a standard part of the non-US gate.
- Diagnostic before fix. The $0 splice-and-verify (English byte-identical, fertilityfertilityHow many tokenizer pieces it takes to spell a word: fertility 1 means whole words survive tokenization, fertility 3 means they arrive in fragments. High fertility hurts sequence labeling directly — the model has to reassemble a word before it can label it, and fragment boundaries are where labels break. Mailwoman measured this on French street names: accented words splitting at the accent ('René' → '▁Ren' + 'é') caused real geocoding misses, and lowering French fertility was worth a tokenizer revision plus a retrain. drop,
Vysokáatomic) proved the mechanism before a single GPU dollar. The expensive retrain came first only because it was the pre-registered plan; the cheap tokenizertokenizerThe component that converts a raw address string into a sequence of numeric token IDs the model can process. Mailwoman's tokenizer is a SentencePiece unigram model trained specifically on postal addresses. probe should have been the opening move. - Verify-before-verdict, twice. The eyeball corrected our own aggregate p50 (parseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates.-bound, not coveragecoverageThe fraction of a population or region for which a data source has real, non-placeholder entries — e.g. 47% rooftop coverage on Texas addresses. Distinct from accuracy on the rows that are present.-bound), and we re-graded the CZ regression in fp32fp32 / fp1632-bit and 16-bit floating-point formats. Mailwoman trains in bf16 (a 16-bit variant) and exports the ONNX model in int8 for size. to rule out int8 quantizationint8 quantizationA model compression technique that stores weights as 8-bit integers instead of 32-bit floats, reducing model size (~4×) with minimal accuracy loss. Mailwoman ships int8-quantized ONNX models (~30 MB) for fast loading in browsers. before blaming trainingtrainingThe process of adjusting a model's parameters so its predictions match labeled examples, by repeatedly measuring error and nudging the weights to reduce it. Distinct from inference, when the trained model is run on new input.. Both saved a wrong conclusion.
- Parallel research that paid off. Four SOTA agents + DeepSeek turned "we have a tokenizertokenizerThe component that converts a raw address string into a sequence of numeric token IDs the model can process. Mailwoman's tokenizer is a SentencePiece unigram model trained specifically on postal addresses. problem" into a ranked, cited fix space with a named, English-safe recipe (FVT mean-init, the Chinese-LLaMA/EEVE lineage).
What could have gone better
- The retrain was the wrong first move, and it was expensive. ~$25 of GPU to falsify a hypothesis a $0 tokenizertokenizerThe component that converts a raw address string into a sequence of numeric token IDs the model can process. Mailwoman's tokenizer is a SentencePiece unigram model trained specifically on postal addresses. probe could have flagged in an hour. The fertilityfertilityHow many tokenizer pieces it takes to spell a word: fertility 1 means whole words survive tokenization, fertility 3 means they arrive in fragments. High fertility hurts sequence labeling directly — the model has to reassemble a word before it can label it, and fragment boundaries are where labels break. Mailwoman measured this on French street names: accented words splitting at the accent ('René' → '▁Ren' + 'é') caused real geocoding misses, and lowering French fertility was worth a tokenizer revision plus a retrain. check should have run before the ship candidate, not after. We reached for the pre-registered lever instead of the cheapest falsifier.
- The 150-row CZ/PL evalevalRunning the model against a held-out golden dataset and computing per-component F1, exact-match, calibration, and resolved-coordinate error. sets are underpowered. The CZ resolved-p50 CI was [−40, −0.34] — barely negative at the top, huge at the bottom. The wrong-citylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy. rate carried the verdict; the p50 was noise. A promote decision needs ~1k rows.
- The first grade in each batchbatch sizeHow many examples the model processes before each parameter update. Larger batches give smoother gradients but cost more memory; gradient accumulation simulates a big batch on a small GPU. kept getting skipped (heat throttle), forcing standalone re-runs. Minor, but it cost a couple of confused minutes each time.
Lessons
- Fragmentation, not data. For diacriticdiacriticAn accent mark that modifies a letter (é, ñ, ç). Address normalization must fold diacritics for matching without discarding the information a user typed.-heavy scripts, a data shardshardA partial output file of the corpus build, written in Parquet format. The training pipeline streams shards row by row. at a frozen tokenizertokenizerThe component that converts a raw address string into a sequence of numeric token IDs the model can process. Mailwoman's tokenizer is a SentencePiece unigram model trained specifically on postal addresses. cannot fix spanspanA contiguous range of characters or tokens in the input string, tagged with an address component type (street, locality, postcode, etc.). Parsed addresses are represented as collections of spans, possibly nested in a tree. boundaries — the tokenizertokenizerThe component that converts a raw address string into a sequence of numeric token IDs the model can process. Mailwoman's tokenizer is a SentencePiece unigram model trained specifically on postal addresses. decides the boundaries. Fix the tokenizertokenizerThe component that converts a raw address string into a sequence of numeric token IDs the model can process. Mailwoman's tokenizer is a SentencePiece unigram model trained specifically on postal addresses..
- The cheapest falsifier goes first. The tokenizertokenizerThe component that converts a raw address string into a sequence of numeric token IDs the model can process. Mailwoman's tokenizer is a SentencePiece unigram model trained specifically on postal addresses. fertilityfertilityHow many tokenizer pieces it takes to spell a word: fertility 1 means whole words survive tokenization, fertility 3 means they arrive in fragments. High fertility hurts sequence labeling directly — the model has to reassemble a word before it can label it, and fragment boundaries are where labels break. Mailwoman measured this on French street names: accented words splitting at the accent ('René' → '▁Ren' + 'é') caused real geocoding misses, and lowering French fertility was worth a tokenizer revision plus a retrain. probe was $0 and decisive; it should have preceded the GPU spend, not followed it.
- Disjoint-codepoint vocabvocabularyThe fixed set of tokens a tokenizer can produce. Mailwoman's SentencePiece vocabulary is tens of thousands of subword pieces, with byte fallback for anything outside it. splicing is a real tool. Appending only non-ASCII piecesECE (Expected Calibration Error). A metric that measures how well a model's confidence scores align with its actual accuracy. Lower is better. Mailwoman's held-out ECE drops from 0.067 (raw) to 0.0035 (calibrated). to a unigram vocabvocabularyThe fixed set of tokens a tokenizer can produce. Mailwoman's SentencePiece vocabulary is tens of thousands of subword pieces, with byte fallback for anything outside it. keeps the source language byte-identical by construction — a guarantee, not a hope. Worth remembering for any future non-Latin extension (with the caveat that it does not scale to CJK, where char-level is the natural unitunitA subdivision of a building — apartment, suite, floor — that refines a street address. Mailwoman's unit component; a designator plus identifier forms a subpremise.).
- A recipe copied from vN-1 inherits vN-1's bugs. Diff the corpuscorpusThe BIO-labeled training data used to train Mailwoman's neural classifier. Assembled from real sources (OpenAddresses, National Address Database) and synthetic shards (boundary stress, order variants, negative space). Managed by @mailwoman/corpus. and source-weightsparameterA single learned number inside a model — one weight or bias. Mailwoman's encoder has roughly 30 million of them; training is the search for good values. against the shipped recipe before launching, not after.
- Mean-init alone can be the whole fix. The 2k fine-tune we assumed we needed added nothing — a good embeddingembeddingA vector of numbers representing a token (or other item) so that similar items sit near each other in vector space. The first thing the model does is turn each token into an embedding. average over already-trained constituents was enough for the existing tagger to read the now- atomic tokentokenOne word or subword in the tokenized input. For the neural classifier, tokens come from SentencePiece (subword units); for the rule classifiers, tokens are whitespace- and punctuation-separated words.. Run the mean-init-only ablation before spending a trainingtrainingThe process of adjusting a model's parameters so its predictions match labeled examples, by repeatedly measuring error and nudging the weights to reduce it. Distinct from inference, when the trained model is run on new input. run; the trainingtrainingThe process of adjusting a model's parameters so its predictions match labeled examples, by repeatedly measuring error and nudging the weights to reduce it. Distinct from inference, when the trained model is run on new input. might be dead weightparameterA single learned number inside a model — one weight or bias. Mailwoman's encoder has roughly 30 million of them; training is the search for good values. (and here it started to overfit).
Where this leaves us
The B vocabvocabularyThe fixed set of tokens a tokenizer can produce. Mailwoman's SentencePiece vocabulary is tens of thousands of subword pieces, with byte fallback for anything outside it.-splice is a clean promote candidate — the successor fix to #825. The ablation resolved the biggest open question: the fix is trainingtrainingThe process of adjusting a model's parameters so its predictions match labeled examples, by repeatedly measuring error and nudging the weights to reduce it. Distinct from inference, when the trained model is run on new input.-free (splice + mean-init, no GPU) and US byte-identity is a guarantee (the encoderencoderThe part of a transformer that turns input tokens into contextualized vector representations. Mailwoman's classifier is a small encoder-only transformer (~30M parameters). is v4.15.0 untouched), which retires the freeze-encoderencoderThe part of a transformer that turns input tokens into contextualized vector representations. Mailwoman's classifier is a small encoder-only transformer (~30M parameters). task before we built it. What remains is mechanical: larger CZ/PL evalevalRunning the model against a held-out golden dataset and computing per-component F1, exact-match, calibration, and resolved-coordinate error. sets (150 rows is underpowered for a promote call), an int8 bundle-size check against the browser SLO (the vocabvocabularyThe fixed set of tokens a tokenizer can produce. Mailwoman's SentencePiece vocabulary is tens of thousands of subword pieces, with byte fallback for anything outside it. growth is a real cost), reproducible build scripts for the splice + mean-init, and a coordinated modelneural classifierThe machine learning model at the core of Mailwoman's parser — a transformer encoder (~30M parameters) trained from scratch to do BIO token classification over addresses. It learns the 'grammar' of address formats; the gazetteer supplies the 'atlas.'+tokenizertokenizerThe component that converts a raw address string into a sequence of numeric token IDs the model can process. Mailwoman's tokenizer is a SentencePiece unigram model trained specifically on postal addresses. version bump. The residual wrong-citylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy. (CZ 28% / PL 11%) re-opens the coveragecoverageThe fraction of a population or region for which a data source has real, non-placeholder entries — e.g. 47% rooftop coverage on Texas addresses. Distinct from accuracy on the rows that are present. lever we correctly deferred — now downstream of a fixed parseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates.. CharCNN was built and validated in parallel and is parked as the CJK-forward path (the one place vocabvocabularyThe fixed set of tokens a tokenizer can produce. Mailwoman's SentencePiece vocabulary is tens of thousands of subword pieces, with byte fallback for anything outside it.-splice won't scale). Tasks #289–#297.
Ledger
| Shift | Day, 2026-07-01, ~15:00–19:45 UTC |
| Modelsneural classifierThe machine learning model at the core of Mailwoman's parser — a transformer encoder (~30M parameters) trained from scratch to do BIO token classification over addresses. It learns the 'grammar' of address formats; the gazetteer supplies the 'atlas.' trained | 2 (v196 ship candidate 80k; v1.9.7-bsplice fine-tune 2k) + the v193 probe finishing |
| Total ModalModalA cloud GPU platform (modal.com) where Mailwoman trains its neural models on NVIDIA A100 GPUs. Training runs are launched via scripts/modal/train_remote.py and typically complete in ~1 hour. GPU | ~$25–30 (retrain dominates; the winning fix — splice + mean-init — needed 0 trainingtrainingThe process of adjusting a model's parameters so its predictions match labeled examples, by repeatedly measuring error and nudging the weights to reduce it. Distinct from inference, when the trained model is run on new input., just an export) |
| Promotions | 0 shipped — v4.15.0 remains default; B is a candidate pending the checklist |
| Regressions shipped | 0 |
| NaNNaN (not a number). A floating-point result for an undefined operation (log of a negative, 0/0). Appearing in the training loss usually halts the run; recovering from it follows the NaN protocol. / divergencedivergenceA training failure where loss descends through warmup, plateaus low for a while, then climbs catastrophically back to its starting magnitude — the model unlearns everything despite no obvious component failure. | 0 |
| Netneural networkA model made of layers of simple numeric units whose connection strengths (weights) are learned from data. The transformer encoder at Mailwoman's core is a neural network. result | #825-as-retrain falsified; an English-safe CZ/PL fix found and validated |