Files
homelab/ansible/roles/llm-inference-multimodel/tasks/models.yml
Hermes Agent service account 5cf4468754 Add Qwen3-8B no-think variant — dual thinking deployment (t_664289a0)
Part A: qwen3-no-think.jinja.j2 Ansible template
  - New template: templates/qwen3-no-think.jinja.j2
    Standard Qwen3 chat template with enable_thinking unconditionally false
    (hardcoded empty <think></think> prefix at add_generation_prompt step).
    Deployed to /opt/models/templates/qwen3-no-think.jinja on astro-orbiter.
  - tasks/models.yml: deploy templates dir + qwen3-no-think.jinja via
    ansible.builtin.template task (tags: models, chat_templates).

Part B: INI preset template — two Qwen3-8B sections
  - templates/llama-server-router-preset.ini.j2:
    [Qwen3-8B-Q4_K_M] — thinking variant, same GGUF, baked-in template.
    [Qwen3-8B-Q4_K_M-no_think] — no-think variant, same GGUF,
    chat-template-file = /opt/models/templates/qwen3-no-think.jinja.
    Both sections: n-gpu-layers=99, ctx-size=32768, flash-attn=true,
    q4_0 KV cache, sleep-idle-seconds=60.

Part C: defaults/main.yml — llama-swap models + matrix
  - llm_swapmode_models: added Qwen3-8B-Q4_K_M (port 8106, GPU) and
    Qwen3-8B-Q4_K_M-no_think (port 8107, GPU, chat_template_file set).
  - llm_swapmode_matrix_rows: row5 (Qwen3-8B thinking + embed),
    row6 (Qwen3-8B no_think + embed). Neither co-resident with Qwen3.8-27B.
  - templates/llama-swap-config.yaml.j2: added chat_template_file support
    (--chat-template-file flag conditional on model.chat_template_file).
  - tasks/swapmode.yml: GATE 2 assert updated 5 -> 7 models.

Part D: war-machine config.yaml (not tracked in git)
  - custom_providers.astro-orbiter.models: added Qwen3-8B-Q4_K_M-no_think
    (context_length: 32768).
  - Reassigned 5 latency-sensitive aux tasks from Meta-Llama-3.1-8B to
    Qwen3-8B-Q4_K_M-no_think: skills_hub, approval, mcp, title_generation,
    profile_describer. Rationale: GPU-resident, lower latency, json_schema OK.
  - web_extract and compression remain on Phi-3.5-mini (long scrapes).

VRAM: both Qwen3-8B variants co-reside with nomic-embed only (~10.4GB +
84MB). Cannot co-reside with Qwen3.8-27B (17.8GB); LRU eviction applies.
2026-08-19 11:35:08 -05:00

104 lines
5.0 KiB
YAML

---
# ------------------------------------------------------------------------------
# FILE: roles/llm-inference-multimodel/tasks/models.yml
# DESCRIPTION: Phase 1 — ensure the production Qwen GGUF is present on disk.
# Idempotent: reuses the stat + size-threshold guard pattern.
#
# HISTORY (2026-08-06): This file previously downloaded Phi-4-14B
# (aux, port 8000) and Mistral-Small-24B (tool-calling, port 8001).
# Both were retired on 2026-08-06 when the deployment was
# consolidated to a single model (Qwen2.5-14B-Instruct-1M, port
# 8002). The download tasks and VRAM co-residency logic were
# removed from this file; see git log if a rollback needs them.
#
# HISTORY (2026-08-07): Qwen2.5-14B-Instruct-1M was superseded by
# Qwen3.6-35B-A3B-UD-Q4_K_S (see task t_2ffc0f63). The model
# was downloaded out-of-band (direct wget per t_2ffc0f63 runbook)
# rather than via this role's get_url pattern. The path and
# variables below are updated to reflect the current production
# model; the download task is a no-op if the file is already
# present (which it is on astro-orbiter as of 2026-08-07+).
#
# 2026-08-12 (t_0cca74a2): Cleaned up stale Phi-4/Mistral tasks
# that referenced undefined variables after the Aug 2026
# consolidation. models.yml now only manages the Qwen3.6-35B
# model that is the sole production model.
# ------------------------------------------------------------------------------
- name: Create models directory
ansible.builtin.file:
path: "{{ llm_models_dir }}"
state: directory
owner: "{{ llm_service_user }}"
group: "{{ llm_service_user }}"
mode: "0755"
become: true
# --- Production model: Qwen3.6-35B-A3B-UD-Q4_K_S (port 8002 / router :8003) -
- name: Check if Qwen3.6-35B GGUF is present on disk
ansible.builtin.stat:
path: "{{ llm_qwen_model_path }}"
register: llm_qwen_model_stat
- name: Report Qwen model presence (model was downloaded out-of-band via t_2ffc0f63)
ansible.builtin.debug:
msg: >-
Qwen model at {{ llm_qwen_model_path }}:
exists={{ llm_qwen_model_stat.stat.exists | default(false) }},
size={{ (llm_qwen_model_stat.stat.size | default(0) | int / 1073741824) | round(2) }}GB
when: llm_qwen_model_stat.stat.exists | default(false)
- name: WARN — Qwen model GGUF not found at expected path
ansible.builtin.debug:
msg: >-
WARNING: Qwen model NOT found at {{ llm_qwen_model_path }}.
This model was originally downloaded via task t_2ffc0f63 (direct wget,
not via this role's get_url). If the file is missing, re-download it
manually or add a get_url task here with the correct HuggingFace URL.
Expected URL (bartowski UD-Q4_K_S):
https://huggingface.co/bartowski/Qwen3.6-35B-A3B-UD-Q4_K_S-GGUF/resolve/main/Qwen3.6-35B-A3B-UD-Q4_K_S.gguf
when: not (llm_qwen_model_stat.stat.exists | default(false))
# --- Staged GGUF models (data-driven, idempotent) ----------------------------
# Ensure every entry in llm_staged_models is present in llm_models_dir with the
# EXACT expected byte size. When present AND size matches, this is a pure
# no-op: no download, no service touch. When a genuine new/mismatched GGUF is
# detected, it is downloaded + ownership/mode corrected and the router restart
# handler is notified so the llama.cpp router re-discovers the models_dir.
# Driven entirely by inventory vars (host_vars) — nothing hardcoded here, so
# adding a future model = append to llm_staged_models in host_vars.
- name: Stage data-driven GGUF models into {{ llm_models_dir }}
ansible.builtin.include_tasks: stage_model.yml
loop: "{{ llm_staged_models | default([]) }}"
loop_control:
loop_var: staged_model
tags: [models]
# --- Chat template overrides ---------------------------------------------------
# Deploy per-model chat template files used by llama-server via chat-template-file.
# These are static files dropped into {{ llm_models_dir }}/templates/.
# t_664289a0: qwen3-no-think.jinja — Qwen3 template with enable_thinking=false
# hardcoded. Used by [Qwen3-8B-Q4_K_M-no_think] in the router preset INI and
# the llama-swap config. The companion [Qwen3-8B-Q4_K_M] section uses the GGUF's
# baked-in template (thinking ON by default).
- name: Ensure chat template directory exists at {{ llm_models_dir }}/templates
ansible.builtin.file:
path: "{{ llm_models_dir }}/templates"
state: directory
owner: "{{ llm_service_user }}"
group: "{{ llm_service_user }}"
mode: "0755"
become: true
tags: [models, chat_templates]
- name: Deploy qwen3-no-think.jinja (thinking=false hard-switch for Qwen3-8B no_think variant)
ansible.builtin.template:
src: qwen3-no-think.jinja.j2
dest: "{{ llm_models_dir }}/templates/qwen3-no-think.jinja"
owner: "{{ llm_service_user }}"
group: "{{ llm_service_user }}"
mode: "0644"
become: true
tags: [models, chat_templates]