Skip to main content

Signal sources and judging

A run learns from its signal source, and, for the sources that generate answers, a selector or grader decides which answers are worth learning from.

The four signal sources​

SourceLearns fromNeedsTraining objective
corpusExample text you supplyA corpus part with a text, messages, or prompt and completion columnSupervised fine-tuning (SFT): learn to reproduce the examples
self-generationThe model's own answers that a selector acceptedA prompt set and a selectorSupervised fine-tuning on the accepted answers
preference-pairsA better and a worse answer to the same promptPreference pairs (chosen and rejected, usually with a prompt)Direct preference optimization (DPO): prefer the chosen answer over the rejected one
rewardSeveral answers per prompt, each scored by a graderA prompt set and a graderGroup-relative policy optimization (GRPO): answers scored above their group's average are reinforced

Every batch a run trains on is recorded as a batch record: where its examples came from (by content hash), which model generated them, and how many answers were accepted, rejected or are still undecided. GET /api/v1/runs/{run_id}/batches lists them.

How corpus text is masked​

For text with a prompt and a completion, only the completion is trained on by default; the prompt's tokens are masked out. A plain-text corpus row is all completion, so every token of it trains. This is the completion_only masking policy (SIGNAL_SFT_MASKING_POLICY). miForge refuses a corpus or self-generation run if no policy is configured, rather than choosing one silently.

Self-generation can drift, so watch it​

A self-generation run that is not really selecting trains on the model's raw output: the loss falls, the test score does not move, and nothing errors. That is why every batch record carries the acceptance rate and its sample size, and the run view warns when a selector accepts or rejects almost everything. Check a selector with a dry run in the pack wizard before you start (see Domain packs).

Reward groups need disagreement​

The reward objective compares each answer with the other answers to the same prompt. A group whose answers all received the same score teaches nothing, so it is refused rather than contributing a silent zero.

Selectors and graders​

A selector gives each answer a verdict: accept, reject or undecided. A grader gives each answer a score. Both are plugins, configured in the pack:

PluginHow it decidesNeeds
RuleA rule written as data (for example, the answer must match a pattern). No model and no network.Nothing. Always available.
Judge modelA second model scores the answer.A judge provider (an OpenAI-compatible endpoint).
Reference matchCompares the answer with a reference answer, exact or fuzzy.A reference in the data.
Human reviewSends the answer to a person through miDataworks' review queue.miDataworks configured.
CompositeCombines other selectors with all, any or majority.Its children's needs.

The model never judges itself​

A judge must be a different model from the one being trained. miForge's in-process provider answers from the model it is training, so it cannot be used as a judge; a judge always goes through a configured endpoint (JUDGE_PROVIDER_BASE_URL and JUDGE_PROVIDER_MODEL). Grading your own homework is not a measurement.

Undecided means undecided​

Human review is asynchronous, so its first verdict is always undecided. An undecided answer is never trained on, and it is never counted as a rejection either. There is no timeout, deadline or setting that turns an undecided answer into an accepted one. A composite selector propagates undecided honestly: all with one undecided child is undecided, not accept.

Trying a selector​

POST /api/v1/selectors/evaluate (the forge_evaluate_completions MCP tool) runs a selector configuration over answers you supply and returns each verdict with its reason, without a run. The New run form also tells you which selector and grader types are available on this installation, and why any are not.