Tinker first-run job

Company and product entity extraction.

We will fine-tune a small LoRA adapter to read a short sentence and return only JSON containing two arrays: companies and products. The job is intentionally small so the first Tinker run tests the workflow, not model ambition.

What Tinker will do.

The Python script owns the data formatting and training loop. Tinker handles the remote GPU work behind the API.

1
Load keypython-dotenv loads TINKER_API_KEY from .env.
2
Create runServiceClient creates a LoRA training client for Qwen/Qwen3-8B.
3
Build DatumPrompt tokens get weight 0. Completion JSON tokens get weight 1.
4
Trainforward_backward_async computes gradients, then optim_step_async updates weights.
5
SampleSave weights and ask held-out prompts to verify JSON extraction behavior.

The output is fixed JSON.

The model should not explain its answer. It should return only the object below, with arrays even when there is one or zero entities.

Prompt shape

The prompt tells the model exactly what to extract and repeats the schema before the JSON: marker.

The prompt is context, so its tokens are masked with weights=0.
Extract company and product names from this text.

Text:
"Microsoft and OpenAI expanded Copilot support for GPT-4o."

Return only JSON with this schema: {"companies":[],"products":[]}

JSON:

Completion shape

The completion is compact JSON. Product names keep their full names even when they include company words.

The completion is the target, so its tokens are trained with weights=1.
{"companies":["Microsoft","OpenAI"],"products":["Copilot","GPT-4o"]}

Examples we train on.

The first run includes both single-company and multi-company sentences so the array behavior is explicit.

Input TextCompaniesProductsWhy It Matters
Apple announced new MacBook Pro models with M4 chips.AppleMacBook Pro, M4basicSimple one-company extraction.
Anthropic launched Claude Opus 4.1 through Amazon Bedrock.Anthropic, AmazonClaude Opus 4.1, Amazon Bedrockmulti-companyCompany appears inside product name too.
Nvidia partnered with Oracle to bring Blackwell GPUs to Oracle Cloud.Nvidia, OracleBlackwell, Oracle Cloudmulti-companyPartnership sentence with cloud product.
Microsoft and OpenAI expanded Copilot support for GPT-4o.Microsoft, OpenAICopilot, GPT-4ocoordinationTwo companies joined by “and”.

How we decide if it worked.

This first test is about validating the Tinker loop and output contract. We should expect some extraction mistakes with such a tiny dataset.

Valid JSON

The output parses with json.loads and contains exactly companies and products.

Entity recall

Expected companies and products are present, including cases with more than one company.

No hallucinations

The model avoids adding entities that are not present in the sentence.

held-out examples
"Salesforce added Agentforce features to Slack."
expected: {"companies":["Salesforce"],"products":["Agentforce","Slack"]}

"Adobe Firefly is now integrated into Photoshop."
expected: {"companies":["Adobe"],"products":["Firefly","Photoshop"]}

"Perplexity launched Comet as an AI browser."
expected: {"companies":["Perplexity"],"products":["Comet"]}

Commands to run it.

The script lives at learning/tinker-thinking-machines/entity_extraction_sft.py.

setup
uv pip install tinker python-dotenv
cp .env.example .env

# Edit .env:
TINKER_API_KEY=your-api-key-here
run
python learning/tinker-thinking-machines/entity_extraction_sft.py

# Optional knobs:
python learning/tinker-thinking-machines/entity_extraction_sft.py \
  --epochs 5 \
  --learning-rate 1e-4 \
  --checkpoint-name entity-extraction-first-test