Views
No views yet
{q, target{cx,cy,h}, zoom, move, ev, wb, flash, pose, say}.contract.py + golden_vectors.json in this repo — the decoder,
golden vectors, and byte-exact VERIFY prompt builder are the integration surface; no
reverse-engineering needed). FRAME/VERIFY shapes are byte-frozen at v0.2; v5-shape decode
verified 4091/4091. New in 0.3.0: wb (−2…+2, absent ⇒ 0) and flash (off|fill,
absent ⇒ off) on PLAN/COACH — both ship conservative in this build (wb emits 0;
treat fill as low-confidence). See HANDOFF.md.| tag | output |
|---|---|
<frame> | frame-shaped JSON (q/target/zoom/move/ev) |
<plan> / <coach> | coach-shaped JSON (+wb/flash/pose/say) |
<verify> plan:{...} | {ok, q, fix, say} — build the prompt with contract.sft_verify_prompt(plan) byte-exact |
contract.decode_frame / decode_coach / decode_verify rather than a bare
json.loads, which is what enforces the ranges and truncations below.| field | type | notes |
|---|---|---|
q | int 0–9 | shot quality; 2 is the no-person default |
target | {cx, cy, h} | where the subject should sit, in percent units of the frame |
zoom | float | multiplier implied by target.h; the app caps auto-zoom at 3× |
move | enum | none/left/right/closer/back — a hint channel; servos act on target |
ev | float | snapped to a fixed 13-step ladder, −2.0…+2.0 |
wb | int −2…+2 | AWB nudge, ~300 K per step; absent ⇒ 0. This build emits 0 |
flash | off/fill | absent or invalid ⇒ off. Low-confidence in this build |
pose | ≤2 strings | ≤5 words each, spoken coaching tips |
fix | ≤2 strings | ≤5 words each, VERIFY only — what still needs correcting |
say | string | ≤8 words, the single line read aloud |
1import torch
2from transformers import AutoProcessor, AutoModelForImageTextToText
3from PIL import Image
4
5REPO = "CasperAtB612/autoportrait-qwen35-08b-v6"
6processor = AutoProcessor.from_pretrained(REPO)
7model = AutoModelForImageTextToText.from_pretrained(REPO, dtype=torch.bfloat16, device_map="auto")
8
9image = Image.open("frame.jpg") # one 3:4 preview frame
10messages = [{"role": "user", "content": [{"type": "image"}, {"type": "text", "text": "<plan>"}]}]
11
12prompt = processor.apply_chat_template(
13 messages, add_generation_prompt=True, enable_thinking=False, # non-thinking mode only
14)
15inputs = processor(text=[prompt], images=[image], return_tensors="pt").to(model.device)
16out = model.generate(**inputs, do_sample=False, max_new_tokens=120) # greedy
17text = processor.decode(out[0][inputs.input_ids.shape[1]:], skip_special_tokens=True)
18
19import contract # contract.py ships in this repo
20print(contract.decode_coach(text))"<plan>" for "<frame>", or for a compliance check pass
contract.sft_verify_prompt(plan) as the text and decode with contract.decode_verify.
The prompt must match byte-for-byte — GOLDEN_SFT_VERIFY_PROMPT in contract.py pins it,
and python contract.py runs the whole contract self-test including the golden vectors.bad-pose-coaching scenario takes the not-ok path), ok-accuracy 0.976.enable_thinking=False); empty <think> scaffold expected.preprocessor_config.json).verify_parity.py --mlx <converted> --emit mlx.jsonl --data-root parity then
--compare parity/hf.jsonl mlx.jsonl — must pass before on-device soak.wb is inert in this build (emits 0, false-nudge rate 0.0) and flash misses its
gates (recall 0.11). Both are safe to decode — the defaults are no-ops — but do not build
UI that expects a nonzero white-balance nudge or trusts "flash":"fill" from this build.move accuracy plateaus around 0.59–0.61 and is label-design-limited, not capacity-limited.q, ev, and say labels are derived deterministically by contract.py; pose
tips are model-annotated with structured output enforced. Any photograph of the developer or
their family was annotated locally on-box only and never sent to a cloud API.contract.py, verify_parity.py,
golden_vectors.json, and the docs. Two carve-outs, both spelled out in LICENSE:Qwen/Qwen3.5-0.8B, is Apache-2.0. That license still governs the
base model's contribution to these derived weights, and its attribution requirements are
not waived by the MIT grant.parity/parity_images/ are third-party photographs (19 Pexels,
1 COCO) included only as a fixed input set for the conversion parity check. They keep
their original licenses, are not sublicensed here, and should not be redistributed as a
collection.