Masked linear
Prepared public-weight linear inference with seeded one-time masks and committed inventory.
The prepared protocol separates client, trusted preparation, and untrusted inference roles. Offline, preparation computes W*r-s from domain-separated client seed batches and pushes committed corrections. Online, inference atomically consumes the ticket matching x-r and returns W*x-s for client reconstruction.
Inventory identity binds model, body, stage, weight, shape, quantization, ring, modulus, wire width, and attempt budget. Rows are one-use and burned on reservation failure, cancellation, replay, or early completion. Preparation is idle during online chat.
This contract assumes protocol-following non-colluding roles and public body weights. Confidential-weight and shared-state protocols are separate.
How the components cooperate
The path has five distinct slots: the protocol defines the wire behavior, preparation creates one-use corrections, placement identifies the inference role, the kernel executes bounded integer matrices, and optional verification checks the result. Use the typed profile to keep these choices compatible rather than treating the individual configuration objects as a running deployment.
API: Masked-linear objects and signatures
Python SDK example
Each section exports a complete experiment.py while changing one slot. Run any
example with pllm gateway --local --experiment experiment.py:experiment --trust-python. Nothing contacts a service or creates inventory until the gateway
passes the experiment to the runtime.
Define the stage protocol with MaskedLinear
MaskedLinear
commits the prepared online exchange: inference receives a ticket and x-r, then
returns W*x-s for client reconstruction.
from pllm import Deployment, ExecutionBudget, Experiment
from pllm.profiles import MaskedLinearCpu
from pllm.protocols import MaskedLinear
from pllm.sources import TinyModel
experiment = Experiment(
name="masked-protocol",
pipeline=MaskedLinearCpu(TinyModel(model_id="masked-tiny"), linear=MaskedLinear()),
deployment=Deployment.local(root="local://masked-protocol"),
budget=ExecutionBudget(requests=1, max_input_tokens=64, max_new_tokens=1),
)
assert experiment.resolve().requires_preparation is TrueProduce corrections with ModelAwareCorrections
ModelAwareCorrections
expands root seeds and uploads model- and stage-bound correction rows before chat.
The preparation guide covers inventory creation and
the alternative research providers.
from pllm import Deployment, ExecutionBudget, Experiment
from pllm.preparation import ModelAwareCorrections
from pllm.profiles import MaskedLinearCpu
from pllm.sources import TinyModel
experiment = Experiment(
name="masked-preparation",
pipeline=MaskedLinearCpu(
TinyModel(model_id="masked-tiny"),
preparation=ModelAwareCorrections(),
),
deployment=Deployment.local(root="local://masked-preparation"),
budget=ExecutionBudget(requests=1, max_input_tokens=64, max_new_tokens=1),
)
assert experiment.pipeline.to_spec()["components"]["preparation"]["component"] == (
"pllm/model-aware-corrections"
)Place public stages with Inference
Inference is placement metadata for
the role that owns the public transformer body and consumes tickets. It is not the
running service itself; parties and offline work
explains the process boundary.
from pllm import Deployment, ExecutionBudget, Experiment
from pllm.profiles import MaskedLinearCpu
from pllm.roles import Inference
from pllm.sources import TinyModel
experiment = Experiment(
name="masked-placement",
pipeline=MaskedLinearCpu(
TinyModel(model_id="masked-tiny"),
inference=Inference(),
),
deployment=Deployment.local(root="local://masked-placement"),
budget=ExecutionBudget(requests=1, max_input_tokens=64, max_new_tokens=1),
)
assert experiment.pipeline.to_spec()["components"]["inference"]["component"] == (
"pllm/inference"
)Execute bounded matrices with Cpu
Cpu selects the persistent native
worker pool. SIMD is chosen at runtime inside this backend rather than represented
as separate profile components. See kernels for direct
matrix execution.
from pllm import Deployment, ExecutionBudget, Experiment
from pllm.kernels import Cpu
from pllm.profiles import MaskedLinearCpu
from pllm.sources import TinyModel
experiment = Experiment(
name="masked-kernel",
pipeline=MaskedLinearCpu(
TinyModel(model_id="masked-tiny"),
kernels=Cpu(threads=2),
),
deployment=Deployment.local(root="local://masked-kernel"),
budget=ExecutionBudget(requests=1, max_input_tokens=64, max_new_tokens=1),
)
assert experiment.pipeline.to_spec()["components"]["kernels"]["params"] == {
"threads": 2,
}Add one-use checks with FreivaldsVerify
FreivaldsVerify lets
the trusted client validate integer stage outputs using authenticated one-use
projections. Select it through VerifiedMaskedLinearCpu; adding the configuration
does not change the preparation role's non-collusion assumption.
from pllm import Deployment, ExecutionBudget, Experiment
from pllm.profiles import VerifiedMaskedLinearCpu
from pllm.sources import TinyModel
from pllm.verification import FreivaldsVerify
experiment = Experiment(
name="verified-masked",
pipeline=VerifiedMaskedLinearCpu(
TinyModel(model_id="verified-tiny"),
verification=FreivaldsVerify(target_failure_bits=48),
),
deployment=Deployment.local(root="local://verified-masked"),
budget=ExecutionBudget(requests=1, max_input_tokens=64, max_new_tokens=1),
)
assert experiment.resolve().verification_target_failure_bits == 48MaskedLinearCpu composes the first four slots. VerifiedMaskedLinearCpu adds the
fifth. Continue to profiles to compare these with direct-FHE and
provider-owned pipelines.