Python
Generates output samples from each source sample using a custom Python synthesize function. Use this when the built-in synthesizers cannot express the transformation you need - for example, expanding one source sample into many, or computing derived fields. For simple placeholder grids, prefer the Template synthesizer.
Output
The list of samples returned by synthesize for each source sample.
Function Signature
Both def and async def are supported. The function receives a single source sample as a dict[str, Any] and must return a list[dict[str, Any]], one dict per output sample.
from typing import Any
def synthesize(source: dict[str, Any]) -> list[dict[str, Any]]:
...Accessing generator config
synthesize can optionally accept a generator_config argument to receive the generator configuration as a plain Python dict. Config values of type dataset are not included.
def synthesize(
source: dict[str, Any],
generator_config: dict[str, Any],
) -> list[dict[str, Any]]:
difficulty_level = generator_config["difficulty_level"]
...Using models from config
To call a model inside the synthesizer, declare it in the generator’s config_spec with type model and access it via generator_config. The model exposes a predict method:
# config_spec:
# - type: model
# key: generate_model
# - type: string
# key: target_language
from latticeflow.core.dtypes import Message
async def synthesize(
source: dict[str, Any],
generator_config: dict[str, Any],
) -> list[dict[str, Any]]:
generate_model = generator_config["generate_model"]
target_language = generator_config["target_language"]
response = await generate_model.predict([
Message(role="system", content=f"Translate the following to {target_language}."),
Message(role="user", content=source["text"]),
])
translated_text = response.text
...Examples
Example: Derived fields. Each source sample of a seed dataset holds a temperature in Celsius. The synthesize function converts it to Fahrenheit - a computation a Jinja template cannot express - and returns two output samples per source sample.
# ...
config_spec:
- key: "source_dataset_key"
type: "dataset"
display_name: "Source Dataset"
default_value: "city-temperatures"
description: "Dataset containing seed temperatures to generate conversion questions from."
definition:
data_source:
type: "dataset_samples"
dataset_key: "<< config.source_dataset_key >>"
synthesizers:
- type: "python"
synthesize_snippet: !include "./synthesize.py"from __future__ import annotations
from typing import Any
def synthesize(source: dict[str, Any]) -> list[dict[str, Any]]:
city = source["city"]
celsius = float(source["temperature_celsius"])
fahrenheit = celsius * 9 / 5 + 32
return [
{
"question": f"It is {celsius:g} °C in {city}. What is that in Fahrenheit?",
"answer": f"{fahrenheit:g} °F",
},
{
"question": f"It is {fahrenheit:g} °F in {city}. What is that in Celsius?",
"answer": f"{celsius:g} °C",
},
]city,temperature_celsius
Berlin,21
Paris,17
Tokyo,26
The 3 seed samples yield 6 output samples:
Generated Dataset
| question | answer |
| :------------------------------------------------- | :------ |
| It is 21 °C in Berlin. What is that in Fahrenheit? | 69.8 °F |
| It is 69.8 °F in Berlin. What is that in Celsius? | 21 °C |
| It is 17 °C in Paris. What is that in Fahrenheit? | 62.6 °F |
| It is 62.6 °F in Paris. What is that in Celsius? | 17 °C |
| It is 26 °C in Tokyo. What is that in Fahrenheit? | 78.8 °F |
| It is 78.8 °F in Tokyo. What is that in Celsius? | 26 °C |
Configuration
Properties
type Literal “python” required
The type of the synthesizer.
synthesize_snippet string, TemplateValue required
The Python snippet defining how output samples are generated from a single source sample. It must define a synthesize function, with the following API:
def synthesize(source: dict[str, Any]) -> list[dict[str, Any]]:where:
sourceis a dictionary representing a single source sample.- The return value is a list of dictionaries, each representing an output sample.
Both def and async def are supported.