Decoding and the best path
The question
At the end of scoring, every piece of the input carries a number for each of the 33 available labelscomponent tagOne of the 25 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..
Taking each piece's highest-scoring labelcomponent tagOne of the 25 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. is the obvious next move, and it is wrong — it produces
sequences that are not readings of anything, like a "continues the localitylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighborhood in the hierarchy." labelcomponent tagOne of the 25 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. with no localitylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighborhood in the hierarchy.
open in front of it. The standard symptom is Saint Petersburg, FL coming back with a localitylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighborhood in the hierarchy. of
Petersburg.
So who assembles 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)., and on what basis?
The analog
In a rule-based parser this is the reconciliation pass, and everyone who has written one has written
it the same way: run the classifiers, look at the mess, and clean it up with tie-breaks. Prefer the
longer 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.. If two rules claim the same 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., prefer the more specific one. Drop a continuation
that has no beginning. If a state abbreviation and a street suffixstreet affixA modifier on a street name indicating type or direction — Street, Avenue, rue, Calle, N, East. Mailwoman tags these as street_prefix / street_suffix, recognized via a morphology FST. both fire on IN, prefer the one
that keeps the rest of the 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. coherent.
Those heuristics are doing something real, and they share a flaw: each one repairs a decision after it was made, in isolation, and the repairs interact. Drop the orphaned continuation and you have silently shortened a town name. Prefer the longer 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. and you have swallowed the house numberhouse numberThe numeric or alphanumeric identifier of a building on a street. Mailwoman's house_number component; its position relative to the street name flips between locales..
The alternative is to stop repairing readings and start scoring them. Instead of picking each piece's best labelcomponent tagOne of the 25 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. and fixing the result, ask which complete reading of the whole line scores highest — where a reading that is not structurally possible scores nothing at all, so it is never in contention and never needs repairing.
That is the difference between a route planner that picks the best next turn at every intersectionintersectionAn address that names a location by two crossing streets ('5th & Main') rather than a number and street. Mailwoman tags the two streets as intersection_a and intersection_b — a negative-space format that starved the early model. and one that scores whole routes. The turn-by-turn planner takes a fast road that dead-ends. The route planner never proposes the dead end, because a route through it is not a route.
Legality first
Before any search runs, the parser builds a table from the labelcomponent tagOne of the 25 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. list, once, that says which labelcomponent tagOne of the 25 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. may follow which. The rule is short enough to state in full:
- Anything may be followed by
O. - Anything may be followed by a
B-labelcomponent tagOne of the 25 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., of any type. A new 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. can always start. I-<type>may follow onlyB-<type>orI-<type>. A continuation must continue something of the same kind.- A sequence may not open on an
I-labelcomponent tagOne of the 25 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.. There is nothing before the first piece to continue.
Everything the table permits scores zero, and everything it forbids scores as impossible. Notice what
the table does not contain: it holds no view about which permitted transition is likely. B-region
followed by B-postcode and B-region followed by B-locality are both legal, and the table ranks
them identically, even though real addresses use the first far more.
That is deliberate, and it is the answer to a question the labelcomponent tagOne of the 25 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. space raises. I-locality without a
B-locality is not an unlikely reading, it is not a reading. Encoding it as a hard constraint means
the orphan cannot appear in any candidate, so nothing downstream has to be defensive about it.
Best path
With the table in hand, the decoderdecoderIn a transformer encoder-decoder model, the part that produces output sequences. Mailwoman's classifier is encoder-only (no decoder); the 'CRF decoder' is a different thing — a structured-prediction layer that picks the best label sequence from the encoder's outputs. scores a whole reading as the sum of its per-piece scores plus its transition scorestransition matrixThe CRF's learned table of per-label-pair scores. It encodes which BIO transitions are preferred or forbidden — e.g. that an I-tag must follow a matching B- or I-., and searches for the highest-scoring legal reading of the entire line. The search is the Viterbi algorithmViterbi decodingA dynamic programming algorithm that finds the most likely sequence of hidden states (labels) given a sequence of observations (token emissions). Mailwoman uses Viterbi over a linear-chain CRF to produce globally coherent BIO label sequences from per-token model scores., which is what makes this affordable: rather than enumerating every combination, it sweeps left to right keeping, for each labelcomponent tagOne of the 25 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. at each position, the best way to reach it, and then walks the backpointers home. Cost is proportional to the number of 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). times the square of the labelcomponent tagOne of the 25 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. count, which for 24 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). and 33 labelscomponent tagOne of the 25 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. is small enough to disappear next to 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.' itself.
Walk the failure it rules out. Suppose 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.' is unsure about Saint in Saint Petersburg —
scoring O a shade above B-locality — and confident about Petersburg as I-locality. Per-piece
argmax takes both winners and emits O, I-locality, which the 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. walk reads as a one-word town.
The best-path search never considers that pair, because the transition is impossible. Its best legal
option pays the small cost on Saint to take B-locality and keeps the large gain on Petersburg.
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.' was not more sure; the reading was better.
Here is the part worth knowing about the shipped 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.', because it changes what the guarantee is for. The classifier accepts a diagnostic per-piece decode alongside the default best-path one, so the two can be compared directly. Run 56 varied inputs through both — lowercase, comma-free, venuevenueA named, non-address place — a business, building, park, or stadium. Mailwoman's free-text point-of-interest component, added as a Tier 2 fine label.-led, fragments, non-Latin script, deliberately broken rows — and they produce byte-identical output on every one. On this 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.', over that set, the constraint rescues nothing you can observe.
That is not an argument for removing it. A 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.' well-fit enough to rarely emit an impossible sequence is not a 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.' that cannot, and the failure is silent when it happens: an orphan continuation does not raise, it shortens a town name. The table costs one table build at startup and a comparison per transition, and in exchange the tree that reaches your code is well-formed on input nobody has tried yet. Guarantees are worth most exactly where measurement has nothing to report.
Why the transition scores are constraints, not weights
A conditional random fieldCRF (Conditional Random Field). A statistical modeling method that predicts structured outputs by modeling dependencies between adjacent labels. Mailwoman uses a linear-chain CRF as the Viterbi decoder at inference time to enforce BIO label consistency — a B-street must be followed by I-street or O, never I-locality. is a sequence 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.' whose decode step scores complete labelcomponent tagOne of the 25 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. sequences using both per-item scores and learned pairwise scores between adjacent labelscomponent tagOne of the 25 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. — the pairwise part being where "regionregionThe first-level administrative subdivision of a country — a US state, a French region, a province. The component between country and locality. is followed by postcodepostcodeThe country-specific postal code (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. more than by localitylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighborhood in the hierarchy." would live, as a real number learned from data.
Mailwoman decodes with ViterbiViterbi decodingA dynamic programming algorithm that finds the most likely sequence of hidden states (labels) given a sequence of observations (token emissions). Mailwoman uses Viterbi over a linear-chain CRF to produce globally coherent BIO label sequences from per-token model scores. over a transition table, so the shape is a conditional random fieldCRF (Conditional Random Field). A statistical modeling method that predicts structured outputs by modeling dependencies between adjacent labels. Mailwoman uses a linear-chain CRF as the Viterbi decoder at inference time to enforce BIO label consistency — a B-street must be followed by I-street or O, never I-locality.'s. The transition table is not. It is built from the labelcomponent tagOne of the 25 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. list at startup, holds only legality, and is never updated by 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.. Nothing in the shipped 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. packages supplies a learned transition matrix; the decoderdecoderIn a transformer encoder-decoder model, the part that produces output sequences. Mailwoman's classifier is encoder-only (no decoder); the 'CRF decoder' is a different thing — a structured-prediction layer that picks the best label sequence from the encoder's outputs. has a slot for one and every published bundleevidence bundleThe pair of retrieval-augmented input channels (street-type + locality-surface) that feed lexicon membership as soft per-token evidence alongside the text. Shipped in 6.7.0; trained natively from step 0 in the from-scratch base line. leaves it empty. 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. scores each piece's labelcomponent tagOne of the 25 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. on its own — cross-entropycross-entropyThe standard classification loss: it penalizes a model for putting low probability on the correct label. Per-token negative log-likelihood is the cross-entropy of each token's label. per position, with no sequence-level term — which is what the model cardmodel cardA JSON metadata file (model-card.json) shipped with each weights bundle. It declares the model version, lineage, label set, required inference channels (anchor, gazetteer), calibration data, and training provenance. records as 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. without a conditional random fieldCRF (Conditional Random Field). A statistical modeling method that predicts structured outputs by modeling dependencies between adjacent labels. Mailwoman uses a linear-chain CRF as the Viterbi decoder at inference time to enforce BIO label consistency — a B-street must be followed by I-street or O, never I-locality. and decoding with one.
One qualification, so the claim is not read wider than it is. A prior can contribute a bonus at a specific transition at a specific position — evidence about one candidate 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., supplied by a gazetteergazetteerA geographical index that maps place names and postcodes to real-world coordinates. Mailwoman uses a custom-built Who's On First (WOF) SQLite database as its gazetteer — the 'atlas' half of the grammar/atlas architecture. lookup and scoped to where it matched. What does not exist is a general preference between two labelscomponent tagOne of the 25 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., learned from data and applied everywhere the pair occurs. That is the thing a learned transition matrixtransition matrixThe CRF's learned table of per-label-pair scores. It encodes which BIO transitions are preferred or forbidden — e.g. that an I-tag must follow a matching B- or I-. would be, and it is the thing that does not ship.
The one-sentence history: a trainable transition matrixtransition matrixThe CRF's learned table of per-label-pair scores. It encodes which BIO transitions are preferred or forbidden — e.g. that an I-tag must follow a matching B- or I-. was built and trained jointly with the per-piece lossloss functionA number measuring how wrong the model's predictions are on a batch of examples. Training minimizes it. Mailwoman's loss combines per-token negative log-likelihood with the CRF sequence loss., the two lossesloss functionA number measuring how wrong the model's predictions are on a batch of examples. Training minimizes it. Mailwoman's loss combines per-token negative log-likelihood with the CRF sequence loss. fought rather than cooperating, and after repeated attempts the sequence-level term was set to zero and has stayed there. What survives is the part that was earning its keep — the legality table — without the part that was not.
What it costs
The decoderdecoderIn a transformer encoder-decoder model, the part that produces output sequences. Mailwoman's classifier is encoder-only (no decoder); the 'CRF decoder' is a different thing — a structured-prediction layer that picks the best label sequence from the encoder's outputs. has no view on what is common. It rules out the impossible and is indifferent among the possible, so a rare-but-legal ordering is never penalized and a frequent one is never rewarded. All of that work sits in 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.', whose scores are computed with the whole line visible rather than piece by piece. The 56-input comparison above is what makes that arrangement look survivable: the per-piece winners already formed a legal sequence on every one of those inputs, which is not what you would see if the scores were being produced without reference to their neighbors.
It cannot fix a confidently wrong labelcomponent tagOne of the 25 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.. Best-path search redistributes among readings the scores make close. When 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.' is sure and wrong, every legal reading agrees with it, and the decoderdecoderIn a transformer encoder-decoder model, the part that produces output sequences. Mailwoman's classifier is encoder-only (no decoder); the 'CRF decoder' is a different thing — a structured-prediction layer that picks the best label sequence from the encoder's outputs. returns the wrong answer in structurally valid form. Valid is not the same as correct — the tree that comes out is always well-formed, and being well-formed is not evidence about the content.
The guarantee stops at the decoderdecoderIn a transformer encoder-decoder model, the part that produces output sequences. Mailwoman's classifier is encoder-only (no decoder); the 'CRF decoder' is a different thing — a structured-prediction layer that picks the best label sequence from the encoder's outputs.. 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. construction downstream is lenient by design: hand it an invalid sequence and it will treat a hanging continuation as the start of a new 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. rather than raising. That tolerance exists so a caller who runs the diagnostic per-piece decode still gets output, and it means the structural guarantee is a property of the default decode path, not of the tree builder.
Related
- Tokens and labels — the labelcomponent tagOne of the 25 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. space this table is built from.
- The gazetteer prior — where the scores the decoderdecoderIn a transformer encoder-decoder model, the part that produces output sequences. Mailwoman's classifier is encoder-only (no decoder); the 'CRF decoder' is a different thing — a structured-prediction layer that picks the best label sequence from the encoder's outputs. reads come from.
- How a model reads an address — the stagestageOne of the dataflow stages in the runtime pipeline (normalize, locale gate, kind classify, phrase group, token classify, sequence correct, reconcile, resolve). Distinct from tier (model vocabulary) and phase (plan milestone). in context.
- Component tags — the tags, and how each becomes two labelscomponent tagOne of the 25 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..