Overview
Quail's behavior can be extended by registering objects on an
ExtensionRegistry. The registry holds models, devices, inference
engines, node types, optimizer rules, and observers. Built-in
components register through the same interface.
Creating a registry
import quail
registry = quail.ExtensionRegistry.with_built_ins()with_built_ins() populates the registry with Quail's included
models, devices, backends, node codecs, and node runtimes. No model
weights are loaded at registration time.
Registering extensions
Each register_* method returns the registry, so calls can be
chained:
registry = (
quail.ExtensionRegistry.with_built_ins()
.register_model(MY_MODEL)
.register_device(MY_DEVICE)
.register_observer(MyObserver)
)Pass the registry when creating a session:
session = quail.Session(config=config, registry=registry)What can be registered
| Method | What it registers |
|---|---|
register_model(spec) | A ModelSpec. |
register_device(spec) | A DeviceSpec. |
register_backend(backend) | A custom inference engine. |
register_observer(factory) | An execution observer. |
register_logical_rule(rule) | A logical plan rewrite rule. |
register_physical_planner(planner) | A planner that proposes physical plans. |
register_physical_rule(rule) | A physical graph rewrite rule. |
register_node(node_type, runtime=...) | A physical node type with its codec and runtime. |
Every name is checked for duplicates. Registering the same name
twice raises ValueError.
Table providers are registered on the session with
session.register(name, provider). They do not go through the
extension registry.
On Modal
Create the registry inside the GPU function. Add extension packages to the Modal image:
image = image.pip_install("my-extension==1.0.0")
image = image.add_local_python_source("my_package")Advanced extension points
Logical rules, physical planners, physical rules, and custom node
types are available for advanced use cases. The source code and test
suite (especially
tests/test_physical.py)
are the best reference for these interfaces.