Skip to main content

Public TML chat types, native tokenizer, and TMLv0 render/parse

Project description

tml-renderers

tml-renderers is the default TML renderer for text and multimodal chat. It packages public message types, a native tokenizer, TMLv0 rendering and parsing, and media codecs for inference and training.

Installation

pip install tml-renderers

tml-renderers is a compiled extension that requires PyTorch 2.10 or newer.

Quickstart

from tml_renderers.chat import Message, MessageList, Text, Author, AuthorKind

message = Message(
    content=Text("Hello, world!"),
    author=Author(AuthorKind.User),
)
messages = MessageList([message])

OpenAI message compatibility

Partners can use OpenAI-shaped message dictionaries at the package boundary without rewriting their chat data into native classes:

from tml_renderers import chat, tokenizers, v0

openai_message_dicts = [
    {"role": "system", "content": "Answer concisely."},
    {"role": "user", "content": "What is 2 + 2?"},
]

openai_messages = chat.OpenAIMessage.from_oss_messages(openai_message_dicts)
round_tripped = chat.OpenAIMessage.to_oss_messages(openai_messages)

renderer = v0.Renderer(tokenizers.o200k_base_chat())
spans, parser = renderer.render_for_completion(openai_messages)

The compatibility surface covers role/content messages, multipart text and image_url content, assistant tool calls, and tool results. render_for_completion and render_for_sft also accept list[OpenAIMessage] directly. This is a message-format bridge; it does not implement the OpenAI network client or server API. Use MessageList.from_oss_messages(...) and MessageList.to_oss_messages() when you want the same conversion through a native MessageList.

Rendering and parsing (TMLv0)

Rendering converts structured chat messages into the exact token and media-span sequence consumed by the model. v0 uses the same TMLv0 grammar for both inference and training:

  • render_for_completion(...) renders an inference prompt and returns a parser for turning generated model tokens back into messages.
  • render_for_sft(...) renders supervised-training examples with aligned, per-token loss weights.

The parser performs the reverse operation, reconstructing structured messages from generated token spans:

from tml_renderers import chat, tokenizers, v0

tokenizer = tokenizers.o200k_base_chat()
renderer = v0.Renderer(tokenizer)

messages = [
    chat.Message(
        content=chat.Text("Hello"),
        author=chat.Author(chat.AuthorKind.User),
    )
]

spans, parser = renderer.render_for_completion(messages)
parsed = parser.parse(spans)

training_examples = renderer.render_for_sft(messages)

The tokenizer is a native o200k BPE tokenizer plus the fixed TMLv0 special tokens. No Hugging Face chat template or remote code is involved.

tokenizer.encode_ordinary("hello")
tokenizer.decode([24912])
tokenizer.encode_special("message_user")   # -> 200000
tokenizer.decode_special(200000)            # -> "message_user"

Full method surface:

method maps on invalid / partial UTF-8
encode_ordinary(text) text → ids — (special-token markup is encoded as literal text)
encode_special(name) name → id raises if name isn't a special token
decode(ids) ids → text lossy — invalid/partial bytes become U+FFFD, never raises (tiktoken parity)
decode_strict(ids) ids → text raises ValueError on invalid/partial UTF-8
decode_bytes(ids) ids → bytes raw bytes, no UTF-8 handling
decode_special(id) id → name None if id isn't a special token

Plus is_special_token(id), special_tokens(), and the eos_token / bos_token / all_special_tokens properties. decode is lossy so a truncated multi-byte tail (common when streaming) renders as rather than raising — reach for decode_strict only when you want that raise.

render_for_completion accepts a MessageList, a list[Message], or a list[OpenAIMessage]. render_for_completion_with_effort(messages, effort) (with effort a float in [0, 1]) inserts a system message containing Thinking effort level: 0.9 before the first non-system message; the messages must not already contain a ThinkingEffort content. For SFT, render_for_sft returns TrainingExamples carrying per-token loss weights.

Media

tml-renderers includes the multimodal codec logic used by the default TMLv0 renderer:

  • An ImagePointer is mapped to the model's black-padded image patch layout and rendered as an ImageAssetPointerTokenSpan with the expected image-token count.
  • An AudioPointer is decoded, resampled to 16 kHz, DMel-encoded, and rendered as a DmelTokenSpan.

Image and audio messages use the same completion and training APIs as text:

from tml_renderers import chat, tokenizers, v0

renderer = v0.Renderer(tokenizers.o200k_base_chat())

image_msg = chat.Message(
    content=chat.ImagePointer(
        location="image.png",
        format=chat.ImageFormat.Png,
        width=512,
        height=512,
    ),
    author=chat.Author(chat.AuthorKind.User),
)

audio_msg = chat.Message(
    content=chat.AudioPointer(
        location="clip.wav",
        format=chat.AudioFormat.Wav,
        num_frames=48_000,
        sample_rate=16_000,
    ),
    author=chat.Author(chat.AuthorKind.User),
)

spans, _ = renderer.render_for_completion([image_msg, audio_msg])
dmel = next(s.span for s in spans if type(s.span).__name__ == "DmelTokenSpan")
print(dmel.dmel.shape)  # [num_audio_tokens, num_dmel_bins], uint8

Media locations are represented as pointers. Audio is read from local files; tml-renderers never fetches remote media.

Streaming

Parser.parse_token / parse_updates / flush_updates return incremental ParseUpdates, so you can render a completion as tokens arrive rather than only returning completed Messages. Each update is a StreamingMessageHeader, a StreamingContent delta, or a completed Message. See tests/test_v0_streaming.py for a worked example.

Token spans

Renderers work with token-span types you can construct directly:

from tml_renderers.chat import (
    EncodedTextTokenSpan,
    ImageAssetPointerTokenSpan,
    ImageFormat,
    PaddingTokenSpan,
    TokenSpan,
)

text = EncodedTextTokenSpan([101, 102])
image = ImageAssetPointerTokenSpan(
    location="image.png", format=ImageFormat.Png, width=512, height=512, num_tokens=256
)
padding = PaddingTokenSpan(4)

# Wrap in the oneof only where a call boundary asks for a TokenSpan.
wrapped = TokenSpan(text)

DmelTokenSpan is the encoded-audio span produced by the renderer's audio handler; dmel is a uint8 tensor of shape [num_audio_tokens, num_dmel_bins].

Using with Tinker

Install the latest Tinker SDK and Tinker Cookbook, then select the tml_v0 renderer in your Cookbook recipe. Cookbook handles model-specific configuration and converts rendered text, image, and audio inputs for sampling and SFT.

The lower-level tml_renderers.tinker helpers are also available when integrating directly with the Tinker SDK. Remote media is never fetched; provide local files or base64 image data.

Types

  • Core: Message, MessageList, Author, AuthorKind, MessageChannel, MessageMetadata
  • Content: Text, Thinking, ThinkingEffort, ImagePointer, AudioPointer, InvokeTool, StructuredToolCall, ToolError, ToolDeclareJson, ModelEndSampling
  • Token spans: TokenSpan, EncodedTextTokenSpan, ImageAssetPointerTokenSpan, DmelTokenSpan, PaddingTokenSpan
  • Formats: ImageFormat, AudioFormat
  • Tool args: ToolArg, ToolMetadata. ToolArg.value is a JSON-encoded value string, matching the OpenAI function.arguments convention.
  • Tool declarations: ToolSpecJson (one declared tool: name / description / type_name, plus parameters as a JSON-schema string; the constructor accepts parameters as a dict and serializes it), grouped into a ToolDeclareJson.

Examples

  • examples/run_tml_v0.py — low-level render/parse of text, tools, and audio.
  • examples/cookbook_tinker_demo.py — OpenAI-style dicts alongside native types.

License

Apache-2.0. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

tml_renderers-0.1.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.7 MB view details)

Uploaded CPython 3.11+manylinux: glibc 2.17+ x86-64

tml_renderers-0.1.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.5 MB view details)

Uploaded CPython 3.11+manylinux: glibc 2.17+ ARM64

tml_renderers-0.1.0-cp311-abi3-macosx_11_0_arm64.whl (4.4 MB view details)

Uploaded CPython 3.11+macOS 11.0+ ARM64

File details

Details for the file tml_renderers-0.1.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for tml_renderers-0.1.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 6f5ff0b08ba5ffe92071cb32215d65cda88d92205850f9f4dd1823f5d0dc2aeb
MD5 f1fdd1e0f89ca761e96ab72f97b0b65a
BLAKE2b-256 26e1e4f8e7acfafaff35b59031b9af308aa059a845a4b094a43bd49dbb729508

See more details on using hashes here.

File details

Details for the file tml_renderers-0.1.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for tml_renderers-0.1.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 52cf4c1b4d1ab2664903f0438e661544546b4d7f0378fe245f53bafc01368014
MD5 2993c6773e187868022f6e14c30a1051
BLAKE2b-256 d6ddc31bb2e874cb11a175f8f14967cee128b2d159507a602b3740152be6a8d6

See more details on using hashes here.

File details

Details for the file tml_renderers-0.1.0-cp311-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tml_renderers-0.1.0-cp311-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f484e983fe42df95c5c69108c7ec4046340f416566f726bd76e211736db29391
MD5 c6aaa38cfee3f5fe53eb817c8d32ed89
BLAKE2b-256 0db312b182a39effd1021263451e6eff0ff47c310f2957706a903ce838935dd5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page