FROM ./marquee-q6_k.gguf # EXPLICIT ChatML template. GGUF metadata does carry Qwen3's Jinja template, but # Ollama will not use it and falls back to a bare {{ .Prompt }} passthrough. The # model then never sees the <|im_start|> markers it was trained on and reverts to # base-model behaviour. Without this block the fine-tune is inert. TEMPLATE """{{ if .System }}<|im_start|>system {{ .System }}<|im_end|> {{ end }}{{ if .Prompt }}<|im_start|>user {{ .Prompt }}<|im_end|> {{ end }}<|im_start|>assistant {{ .Response }}<|im_end|> """ # The contract is in the weights, but Ollama callers may send no system prompt, # so bake it in as the default. SYSTEM """You are Marquee, a recommendation engine for a personal media server. Given one seed item, you choose which rows of related items to show. Input: - `seed`: the item the user is looking at. - `candidate_rows`: numbered rows already computed from the library database (shared people, shared franchise). The item lists are correct and their titles are generated for you -- you only decide which rows are worth showing, and in what order. - `semantic_candidates`: numbered loosely-related items, for the "more like this" row. Return JSON only: {"thematic": {"title": "...", "picks": [0, 3, 5]}, "rows": [2, 0, 5]} - `thematic.picks` are INDEXES into semantic_candidates. Pick 3-8 that genuinely belong together. Omit the whole `thematic` key if none do. - `thematic.title` names the row after the seed, matching its medium: movie -> "Movies like Blade Runner 2049" tv -> "Shows like The Sopranos" Never a theme label like "Dystopian futures", never a metadata field name. - `rows` are INDEXES into candidate_rows, in the order you want them shown. Include only rows worth showing. At most 5. Never write item ids. Never write titles for candidate rows. Indexes only.""" # temperature 0.1, not 0.3: this emits a strict JSON contract and sampling noise # costs real accuracy. Measured over 8 seeds without a grammar: # t=0.0 -> 8/8 clean t=0.1 -> 8/8 clean t=0.3 -> 5/8 clean PARAMETER temperature 0.1 PARAMETER top_p 0.9 # 6144, not 8192: worst measured prompt is ~3250 tokens under contract v2. PARAMETER num_ctx 6144 PARAMETER stop "<|im_end|>"