Selection is separate from logits
The package receives a vocabulary-sized logit span. Model execution remains outside the sampling layer.
UAIX.LmRuntime / Package guide
Greedy and probability sampling, logit processing, deterministic state, and stop handling.
Required For token selection and stop handling
UAIX.LmRuntime.Sampling
Greedy and probability sampling, logit transforms, deterministic random state, top-k/top-p filtering, stop matching, and generation control.
Samplers and logits processors for pure C# local LLM runtime generation.
dotnet add package UAIX.LmRuntime.Sampling
<PackageReference Include="UAIX.LmRuntime.Sampling" />
Version policy: The documentation deliberately omits UAIX.LmRuntime package version numbers. Resolve and pin versions through your normal dependency-management and lock-file process.
The package receives a vocabulary-sized logit span. Model execution remains outside the sampling layer.
SamplingState owns deterministic random state and token-frequency history, so callers control whether state persists across generation steps.
StopSequenceMatcher retains partial UTF-8 byte prefixes across appended chunks and distinguishes visible output from matched stop bytes.
These are the main public entry points. The generated reference below includes the documented public package surface.
GreedySampler ProbabilitySampler SamplingOptions SamplingState LogitProcessor TopKSelector StopSequenceMatcher GenerationController Xoshiro256StarStar Examples use the documented public package surface. Paths, identities, runtime identifiers, device evidence, and application policy remain host inputs.
Choose the highest logit without allocating a probability distribution.
using UAIX.LmRuntime.Sampling;
ReadOnlySpan<float> logits = [-1.2f, 0.5f, 2.75f, 1.1f];
int tokenId = GreedySampler.Select(logits);
Console.WriteLine($"Selected token: {tokenId}");
Create SamplingState once per generation sequence so random and repetition state advance together.
using UAIX.LmRuntime.Sampling;
public static class ReproducibleSamplingExample
{
/// <summary>
/// Selects one token from logits using an explicitly seeded sampling state.
/// </summary>
/// <param name="logits">The vocabulary logits for the current decoding step.</param>
/// <returns>The selected token and candidate evidence.</returns>
public static SamplingDecision Select(ReadOnlySpan<float> logits)
{
if (logits.IsEmpty)
{
throw new ArgumentException("At least one logit is required.", nameof(logits));
}
var options = new SamplingOptions
{
Temperature = 0.8f,
TopK = Math.Min(40, logits.Length),
TopP = 0.95f,
MinimumP = 0.05f,
RepetitionPenalty = 1.1f,
FrequencyPenalty = 0,
PresencePenalty = 0,
MinimumGeneratedTokens = 0,
MaximumGeneratedTokens = 128,
MaximumContextTokens = 8_192,
Seed = 42
};
options.Validate(vocabularySize: logits.Length);
var state = new SamplingState(options);
SamplingDecision decision =
ProbabilitySampler.Select(logits, options, state);
state.RecordToken(decision.TokenId);
return decision;
}
}
Boundary: Reproducibility also requires the same logits, tokenizer, settings, token history, and runtime math path.
Inspect the transformed logits independently from token selection.
using UAIX.LmRuntime.Sampling;
public static class LogitProcessingExample
{
/// <summary>
/// Applies caller-selected bias and history penalties to one logit vector.
/// </summary>
/// <param name="logits">The unmodified vocabulary logits.</param>
/// <returns>A processed copy suitable for token selection.</returns>
public static float[] Process(ReadOnlySpan<float> logits)
{
if (logits.Length < 2)
{
throw new ArgumentException(
"At least two logits are required for this example.",
nameof(logits));
}
var options = new SamplingOptions
{
Temperature = 1.0f,
RepetitionPenalty = 1.15f,
FrequencyPenalty = 0.2f,
PresencePenalty = 0.1f,
LogitBias = new Dictionary<int, float>
{
[0] = -2.0f,
[1] = 1.5f
},
Seed = 7
};
options.Validate(vocabularySize: logits.Length);
var state = new SamplingState(options);
state.RecordToken(0);
state.RecordToken(0);
return LogitProcessor.Process(logits, options, state);
}
}
Detect a stop string even when its UTF-8 bytes span multiple generated tokens.
using System.Text;
using UAIX.LmRuntime.Sampling;
var matcher = new StopSequenceMatcher(
stopSequences: ["</answer>"],
includeMatchedBytes: false);
StopSequenceMatchResult first = matcher.Append(
Encoding.UTF8.GetBytes("Result</ans"));
StopSequenceMatchResult second = matcher.Append(
Encoding.UTF8.GetBytes("wer>ignored"));
byte[] remaining = matcher.Complete();
Console.Write(Encoding.UTF8.GetString(first.VisibleBytes));
Console.Write(Encoding.UTF8.GetString(second.VisibleBytes));
Console.Write(Encoding.UTF8.GetString(remaining));
Expand a type to review its documented public fields, properties, constructors, methods, parameter descriptions, and return descriptions.
GenerationFinishReasonUAIX.LmRuntime.Sampling
7 members
Identifies the first decisive condition that ended a generation.
None
Generation remains active.
StopToken
An exact configured token identifier ended generation.
StopText
A configured decoded UTF-8 stop sequence ended generation.
TokenLimit
The configured maximum generated-token count was reached.
ContextLimit
The configured prompt-plus-generation context bound was reached.
Cancelled
Cancellation was observed before publishing another token.
ExecutionError
An execution error ended generation.
GenerationUsageUAIX.LmRuntime.Sampling
3 members
Records tokenizer-ID-based usage accounting.
PromptTokens
Gets the exact number of prompt token identifiers consumed.
CompletionTokens
Gets the exact number of generated token identifiers accepted by the controller.
TotalTokens
Gets the checked sum of prompt and completion token counts.
GenerationStepResultUAIX.LmRuntime.Sampling
3 members
Represents the observable result of attempting to publish one generated token.
TokenAccepted
Gets whether the token identifier was retained in generated-token output.
VisibleBytes
Gets bytes newly safe to publish after stop-prefix matching.
FinishReason
Gets the stable finish reason after this step.
GenerationControllerUAIX.LmRuntime.Sampling
9 members
Enforces stop, limit, cancellation, usage, and output-publication boundaries for one generation.
GenerationController(int,int,UAIX.LmRuntime.Sampling.SamplingOptions)
Initializes a controller from validated vocabulary and prompt-token bounds.
vocabularySizepromptTokenCountoptionsState
Gets the session-local sampling state used by the same generation.
OutputTokenIds
Gets generated token identifiers retained under stop-token emission policy.
FinishReason
Gets the first decisive finish reason, or while active.
Usage
Gets exact tokenizer-ID usage without deriving counts from text or bytes.
AcceptToken(int,System.ReadOnlySpan<byte>,System.Threading.CancellationToken)
Attempts to accept and publish one generated token at a bounded cancellation point.
tokenIddecodedBytescancellationTokenReturns: The token/output/finish transition produced by this step.
ObserveCancellation(System.Threading.CancellationToken)
Observes cancellation between decode steps without publishing another token.
cancellationTokenReturns: The GenerationFinishReason result produced by GenerationController.ObserveCancellation for this contract: Observes cancellation between decode steps without publishing another token. It is published only after all documented validation and ownership transitions succeed.
Fail(System.Exception)
Records an execution failure without exposing exception details through the stable finish reason.
exceptionReturns: The GenerationFinishReason result produced by GenerationController.Fail for this contract: Records an execution failure without exposing exception details through the stable finish reason. It is published only after all documented validation and ownership transitions succeed.
CompleteVisibleBytes
Completes an otherwise active stream and flushes any bytes retained as a possible stop prefix.
Returns: Remaining visible bytes; the finish reason remains GenerationFinishReason.None.
GreedySamplerUAIX.LmRuntime.Sampling
1 member
Provides deterministic greedy token selection with explicit non-finite input policy.
Select(System.ReadOnlySpan<float>)
Selects the highest logit index with deterministic lower-index tie-breaking.
logitsReturns: The int value computed by GreedySampler.Select for this contract: Selects the highest logit index with deterministic lower-index tie-breaking. Range, finite-value, and overflow checks are completed before the value is returned.
LogitProcessorUAIX.LmRuntime.Sampling
4 members
Applies validated, deterministic token-history and bias policies to logits.
Process(System.ReadOnlySpan<float>,UAIX.LmRuntime.Sampling.SamplingOptions,UAIX.LmRuntime.Sampling.SamplingState)
Produces a processed copy of the source logits without exposing partially mutated caller data on validation failure.
logitsoptionsstateReturns: A newly allocated float[] containing the ordered result of LogitProcessor.Process: Produces a processed copy of the source logits without exposing partially mutated caller data on validation failure. The caller owns the returned array and later mutation cannot alter the source object.
ApplyHistoryPenalties(System.Span<float>,UAIX.LmRuntime.Sampling.SamplingOptions,System.Collections.Generic.IReadOnlyDictionary<int,int>)
Applies sign-aware repetition, frequency, and presence penalties in one deterministic pass.
logitsoptionstokenCountsApplyBias(System.Span<float>,System.Collections.Generic.IReadOnlyDictionary<int,float>)
Adds all validated per-token biases exactly once.
logitsbiasesSuppressEarlyStopTokens(System.Span<float>,UAIX.LmRuntime.Sampling.SamplingOptions,int)
Marks configured stop tokens ineligible before the exact minimum-token boundary.
logitsoptionsgeneratedTokenCountLogitScoreUAIX.LmRuntime.Sampling
2 members
Represents a scored token candidate.
TokenIndex
Gets the token index.
Score
Gets the logit score.
SamplingCandidateUAIX.LmRuntime.Sampling
2 members
Represents one normalized token candidate retained after all filters.
TokenId
Gets the token identifier.
Probability
Gets the normalized candidate probability.
SamplingDecisionUAIX.LmRuntime.Sampling
3 members
Describes one deterministic or stochastic sampling decision.
TokenId
Gets the selected token identifier.
IsGreedy
Gets whether the zero-temperature greedy path made the decision.
Candidates
Gets the candidate distribution used for selection, ordered by probability and token identifier.
ProbabilitySamplerUAIX.LmRuntime.Sampling
2 members
Builds stable normalized distributions and samples them with session-local deterministic state.
Select(System.ReadOnlySpan<float>,UAIX.LmRuntime.Sampling.SamplingOptions,UAIX.LmRuntime.Sampling.SamplingState)
Processes logits and selects one token under the supplied deterministic policy.
logitsoptionsstateReturns: The SamplingDecision result produced by ProbabilitySampler.Select for this contract: Processes logits and selects one token under the supplied deterministic policy. It is published only after all documented validation and ownership transitions succeed.
BuildDistribution(System.ReadOnlySpan<float>,UAIX.LmRuntime.Sampling.SamplingOptions)
Builds a stable, filtered, and normalized probability distribution without consuming random state.
processedLogitsoptionsReturns: Candidates ordered by descending probability and ascending token identifier for ties.
SamplingOptionsUAIX.LmRuntime.Sampling
17 members
Defines deterministic logit-processing, candidate-selection, and generation-stop policies for one sampling session.
Instances are treated as immutable configuration after a is created. Validation is intentionally performed before a logit buffer is modified so an invalid option cannot leave partially adjusted data.
Temperature
Gets the non-negative temperature. Zero selects the deterministic greedy path.
TopK
Gets the maximum candidate count. Zero disables top-k filtering.
TopP
Gets the normalized nucleus probability threshold in the inclusive range zero through one.
MinimumP
Gets the minimum probability relative to the highest candidate probability.
RepetitionPenalty
Gets the positive sign-aware repetition penalty.
FrequencyPenalty
Gets the amount subtracted for each prior occurrence of a token.
PresencePenalty
Gets the amount subtracted once from any token that has previously appeared.
LogitBias
Gets finite per-token additive logit biases.
StopTokenIds
Gets exact token identifiers that terminate generation after the minimum-token boundary.
StopSequences
Gets UTF-8 stop strings matched across decoded token boundaries.
IncludeStopToken
Gets whether a matched stop token is retained in emitted token identifiers.
IncludeStopSequence
Gets whether matched stop-sequence bytes are included in visible output.
MinimumGeneratedTokens
Gets the minimum generated-token count before stop-token or stop-text policies become eligible.
MaximumGeneratedTokens
Gets the maximum number of generated tokens. Zero permits no generated tokens.
MaximumContextTokens
Gets the maximum prompt-plus-generation token count.
Seed
Gets the deterministic per-session pseudo-random generator seed.
Validate(int)
Validates every option and token-indexed policy against a vocabulary size without mutating caller data.
vocabularySizeSamplingStateUAIX.LmRuntime.Sampling
6 members
Stores token history and deterministic pseudo-random state for exactly one generation session.
A state instance must not be shared by independent requests. Keeping history and random state together makes session isolation explicit and prevents interleaved requests from consuming one another's random sequence.
SamplingState(UAIX.LmRuntime.Sampling.SamplingOptions)
Initializes isolated state from the immutable session options.
optionsRandom
Gets the session-local deterministic random generator.
GeneratedTokenCount
Gets the number of generated token identifiers recorded by this session.
TokenCounts
Gets the session-owned prior-token counts through a read-only interface.
RecordToken(int)
Records one generated token for repetition, frequency, presence, and usage policies.
tokenIdGetTokenCount(int)
Gets the prior count for one token without adding it to history.
tokenIdReturns: The recorded count, or zero when the token has not appeared.
Xoshiro256StarStarUAIX.LmRuntime.Sampling
3 members
Implements the xoshiro256** generator with SplitMix64 seed expansion and deterministic unsigned arithmetic.
The generator is intentionally session-local and not thread-safe. Its transition follows the published xoshiro256** reference algorithm; seed expansion prevents the prohibited all-zero state for a zero seed.
Xoshiro256StarStar(ulong)
Initializes the generator from one deterministic 64-bit seed.
seedNextUInt64
Returns the next 64-bit output and advances the generator exactly once.
Returns: The ulong value computed by Xoshiro256StarStar.NextUInt64 for this contract: Returns the next 64-bit output and advances the generator exactly once. Range, finite-value, and overflow checks are completed before the value is returned.
NextUnitDouble
Returns a uniformly distributed value in the half-open interval [0, 1).
Returns: The double value computed by Xoshiro256StarStar.NextUnitDouble for this contract: Returns a uniformly distributed value in the half-open interval [0, 1). Range, finite-value, and overflow checks are completed before the value is returned.
StopSequenceMatchResultUAIX.LmRuntime.Sampling
3 members
Represents visible bytes released by one bounded stop-sequence matching step.
VisibleBytes
Gets newly visible bytes that cannot participate in a future stop match.
MatchedStopSequence
Gets the exact stop string that completed during this step, if any.
Matched
Gets whether a terminal stop sequence has matched.
StopSequenceMatcherUAIX.LmRuntime.Sampling
5 members
Matches UTF-8 stop sequences across arbitrary decoded-byte boundaries while retaining only a bounded possible prefix.
StopSequenceMatcher(System.Collections.Generic.IEnumerable<string>,bool)
Initializes a matcher from non-empty stop strings.
stopSequencesincludeMatchedBytesMaximumRetainedBytes
Gets the maximum retained prefix bytes, bounded by the longest configured stop sequence.
RetainedByteCount
Gets the current possible stop-prefix byte count.
Append(System.ReadOnlySpan<byte>)
Appends one decoded byte chunk and releases bytes that can no longer participate in a stop match.
bytesReturns: The newly visible bytes and optional terminal match.
Complete
Completes matching and releases any retained non-matching prefix bytes.
Returns: A newly allocated byte[] containing the ordered result of StopSequenceMatcher.Complete: Completes matching and releases any retained non-matching prefix bytes. The caller owns the returned array and later mutation cannot alter the source object.
TopKSelectorUAIX.LmRuntime.Sampling
1 member
Provides partial top-k selection for logit arrays.
SelectTopK(System.ReadOnlySpan<float>,int)
Selects the highest scoring token candidates without sorting the full input.
logitskReturns: The selected candidates in descending score order with deterministic index tie-breaking.
Use it for deterministic argmax generation, parity tests, and local facade paths that intentionally do not expose probabilistic settings.
Create one state per generation sequence and retain it across steps. Starting a new state resets random progression and token-frequency history.
No. It controls the package random generator. Identical output still depends on identical logits, processing settings, token history, tokenizer, floating-point behavior, and model execution.
Generated tokens may split one Unicode scalar or stop string across token boundaries. Byte-level retention avoids decoding incomplete fragments prematurely.