From 0c86a76968cd8a4529c87e25161ec5dff0e12e5f Mon Sep 17 00:00:00 2001 From: Hyperling Date: Fri, 9 Oct 2026 11:43:46 -0700 Subject: [PATCH] zeroclaw, greatly simplify the choosing of LLMs based on resources, refactor ollama run file, modify some of the env values, add qwen-code, change some of the models in the download queue. --- tasks/workstation/linux/software/zeroclaw.yml | 272 +++++------------- 1 file changed, 74 insertions(+), 198 deletions(-) diff --git a/tasks/workstation/linux/software/zeroclaw.yml b/tasks/workstation/linux/software/zeroclaw.yml index 664dd14..58cb0d1 100644 --- a/tasks/workstation/linux/software/zeroclaw.yml +++ b/tasks/workstation/linux/software/zeroclaw.yml @@ -31,84 +31,18 @@ ollama: ollama zeroclaw: zeroclaw zerocode: zerocode - llm_concurrency: 1 # "{{ ansible_processor_vcpus / 4 | round(0, method='ceil') | int }}" - llm_installs: [] - llm_tier0_cpu: 1 - llm_tier0_ram: 2000 - llm_tier0: - - { "model": "qwen3.5:0.8b", "provider": "qwen_35_0008" } - - { "model": "qwen2.5-coder:0.5b", "provider": "qwen_25_coder_0005" } - - { "model": "qwen2.5-coder:1.5b", "provider": "qwen_25_coder_0015" } - llm_tier1_cpu: 2 - llm_tier1_ram: 4000 - llm_tier1: - - { "model": "qwen3.5:2b", "provider": "qwen_35_0020" } - - { "model": "qwen2.5-coder:3b", "provider": "qwen_25_coder_0030" } - llm_tier2_cpu: 3 - llm_tier2_ram: 6000 - llm_tier2: - - { "model": "qwen3.5:4b", "provider": "qwen_35_0040" } - - { "model": "qwen2.5-coder:7b", "provider": "qwen_25_coder_0070" } - llm_tier3_cpu: 4 - llm_tier3_ram: 8000 - llm_tier3: - - { "model": "qwen3.5:9b", "provider": "qwen_35_0090" } - - { "model": "qwen2.5-coder:14b", "provider": "qwen_25_coder_0140" } - llm_tier4_cpu: 6 - llm_tier4_ram: 12000 - llm_tier4: [] - llm_tier5_cpu: 10 - llm_tier5_ram: 20000 - llm_tier5: - #- { "model": "devstral-small-2:24b", "provider": "devstral_20_0240_small" } - #- { "model": "qwen3.8:27b", "provider": "qwen_38_0270" } - llm_tier6_cpu: 12 - llm_tier6_ram: 30000 - llm_tier6: - #- { "model": "qwen3.6:35b", "provider": "qwen_36_0350" } - - { "model": "qwen3.5:35b", "provider": "qwen_35_0350" } - - { "model": "qwen3-coder:30b", "provider": "qwen_30_coder_0300" } - - { "model": "qwen2.5-coder:32b", "provider": "qwen_25_coder_0320" } - llm_tier7_cpu: 16 - llm_tier7_ram: 64000 - llm_tier7: [] - llm_tier8_cpu: 32 - llm_tier8_ram: 320000 - llm_tier8: - - { "model": "qwen3.5:122b", "provider": "qwen_35_1220" } - llm_tier9_cpu: 64 - llm_tier9_ram: 999000 - llm_tier9: - - { "model": "qwen3-coder:420b", "provider": "qwen_30_coder_4200" } - llm_removals: - # tier0 # - # tier1 # - - { "model": "qwen3:4b", "provider": "qwen_30_0040" } - # tier2 # - # tier3 # - # tier4 # - - { "model": "qwen3.6:27b", "provider": "qwen_36_0270" } - - { "model": "qwen3.5:27b", "provider": "qwen_35_0270" } - # tier5 # - # tier9 # - - ##### TBD ##### - ### 2.5, does not have "thinking" as an attribute, tempting! - #- qwen2.5:0.5b - #- qwen2.5:1.5b - #- qwen2.5:3b - #- qwen2.5:7b - #- qwen2.5:14b - #- qwen2.5:32b - #- qwen2.5:72b - ### Others - #- deepseek-r1:1.5b - #- deepseek-r1:7b - #- mistral:7b - #- ministral-3:3b - #- ministral-3:8b - #- ministral-3:14b - #- glm4-flash + qwen_code: qwen-code + # Good for preventing swap usage. + llm_concurrency: 1 + # Allow having multiple chats open without them just waiting each other. + llm_parallel: "{{ ansible_processor_vcpus / 4 | round(0, method='ceil') | int }}" + # Most LLMs take a coefficient of about 1.2 to 1.5 of their file size in + # RAM, which is usually less than guessing a usage of weight*1000. + # Example: + # - qwen3.5:9b would be 6.6GB * 1.3 = 8580, rather than 9000. + # Conversely: + # - qwen3.5:4b would be 3.3GB * 1.3 = 4290, rather than 4000. + llm_size_coef: 1.3 - name: Workstation | Linux | Software | ZeroClaw | Facts 02 ansible.builtin.set_fact: @@ -131,125 +65,63 @@ ollama_runit_log_script: "{{ ollama_runit_log_dir }}/{{ runit_log_script }}" zeroclaw_runit_log_script: "{{ zeroclaw_runit_log_dir }}/{{ runit_log_script }}" - - name: Workstation | Linux | Software | ZeroClaw | Facts | Merge | tier0 + - name: Workstation | Linux | Software | ZeroClaw | Facts | LLMs ansible.builtin.set_fact: - llm_installs: "{{ llm_installs + llm_tier0 }}" - when: ansible_processor_vcpus >= llm_tier0_cpu - and ansible_memtotal_mb >= llm_tier0_ram + llm_installs: [] + llm_removals: + - { "model": "qwen3:4b", "provider": "qwen_30_0040" } + - { "model": "qwen3.6:27b", "provider": "qwen_36_0270" } + - { "model": "qwen3.5:27b", "provider": "qwen_35_0270", "size_mb": llm_size_coef * 17000 } + llm_choices: + ### QWEN >3.5 - Need to try! + - { "model": "qwen3.8:27b", "provider": "qwen_38_0270", "size_mb": 27000 } + - { "model": "qwen3.6:35b", "provider": "qwen_36_0350", "size_mb": 35000 } + ### QWEN 3.5 - Good for generic usage and a little coding. + - { "model": "qwen3.5:0.8b", "provider": "qwen_35_0008", "size_mb": llm_size_coef * 1200 } + - { "model": "qwen3.5:2b", "provider": "qwen_35_0020", "size_mb": llm_size_coef * 2700 } + - { "model": "qwen3.5:4b", "provider": "qwen_35_0040", "size_mb": llm_size_coef * 3300 } + - { "model": "qwen3.5:9b", "provider": "qwen_35_0090", "size_mb": llm_size_coef * 6600 } + # skip 27b and use 35b + - { "model": "qwen3.5:35b", "provider": "qwen_35_0350", "size_mb": llm_size_coef * 22000 } + - { "model": "qwen3.5:122b", "provider": "qwen_35_1220", "size_mb": llm_size_coef * 81000 } + ### QWEN 3.0 Coder - Supposed to be better than 2.5 for machines that can handle it. + - { "model": "qwen3-coder:30b", "provider": "qwen_30_coder_0300", "size_mb": llm_size_coef * 19000 } + - { "model": "qwen3-coder:420b", "provider": "qwen_30_coder_4200", "size_mb": llm_size_coef * 290000 } + ### QWEN 2.5 Coder - Ol'reliable! + - { "model": "qwen2.5-coder:0.5b", "provider": "qwen_25_coder_0005", "size_mb": llm_size_coef * 398 } + - { "model": "qwen2.5-coder:1.5b", "provider": "qwen_25_coder_0015", "size_mb": llm_size_coef * 986 } + - { "model": "qwen2.5-coder:3b", "provider": "qwen_25_coder_0030", "size_mb": llm_size_coef * 1900 } + - { "model": "qwen2.5-coder:7b", "provider": "qwen_25_coder_0070", "size_mb": llm_size_coef * 4700 } + - { "model": "qwen2.5-coder:14b", "provider": "qwen_25_coder_0140", "size_mb": llm_size_coef * 9000 } + - { "model": "qwen2.5-coder:32b", "provider": "qwen_25_coder_0320", "size_mb": llm_size_coef * 20000 } + ### Mistral, Ministral, and Devstral - By a French company? + - { "model": "devstral-small-2:24b", "provider": "devstral_20_0240_small", "size_mb": 24000 } + #- mistral:7b + #- ministral-3:3b + #- ministral-3:8b + #- ministral-3:14b + ##### TBD ##### + ### QWEN 2.5 - Older, but does not have "thinking", tempting! + #- qwen2.5:0.5b + #- qwen2.5:1.5b + #- qwen2.5:3b + #- qwen2.5:7b + #- qwen2.5:14b + #- qwen2.5:32b + #- qwen2.5:72b + ### Z.ai + #- GLM-5.x + #- glm4-flash + ### Others + #- deepseek-r1:1.5b + #- deepseek-r1:7b - - name: Workstation | Linux | Software | ZeroClaw | Facts | Merge | tier0 | Uninstall + - name: Workstation | Linux | Software | ZeroClaw | Facts | Choices | Sort ansible.builtin.set_fact: - llm_removals: "{{ llm_removals + llm_tier0 }}" - when: ansible_processor_vcpus < llm_tier0_cpu - or ansible_memtotal_mb < llm_tier0_ram - - - name: Workstation | Linux | Software | ZeroClaw | Facts | Merge | tier1 - ansible.builtin.set_fact: - llm_installs: "{{ llm_installs + llm_tier1 }}" - when: ansible_processor_vcpus >= llm_tier1_cpu - and ansible_memtotal_mb >= llm_tier1_ram - - - name: Workstation | Linux | Software | ZeroClaw | Facts | Merge | tier1 | Uninstall - ansible.builtin.set_fact: - llm_removals: "{{ llm_removals + llm_tier1 }}" - when: ansible_processor_vcpus < llm_tier1_cpu - or ansible_memtotal_mb < llm_tier1_ram - - - name: Workstation | Linux | Software | ZeroClaw | Facts | Merge | tier2 - ansible.builtin.set_fact: - llm_installs: "{{ llm_installs + llm_tier2 }}" - when: ansible_processor_vcpus >= llm_tier2_cpu - and ansible_memtotal_mb >= llm_tier2_ram - - - name: Workstation | Linux | Software | ZeroClaw | Facts | Merge | tier2 | Uninstalls - ansible.builtin.set_fact: - llm_removals: "{{ llm_removals + llm_tier2 }}" - when: ansible_processor_vcpus < llm_tier2_cpu - or ansible_memtotal_mb < llm_tier2_ram - - - name: Workstation | Linux | Software | ZeroClaw | Facts | Merge | tier3 - ansible.builtin.set_fact: - llm_installs: "{{ llm_installs + llm_tier3 }}" - when: ansible_processor_vcpus >= llm_tier3_cpu - and ansible_memtotal_mb >= llm_tier3_ram - - - name: Workstation | Linux | Software | ZeroClaw | Facts | Merge | tier3 | Uninstalls - ansible.builtin.set_fact: - llm_removals: "{{ llm_removals + llm_tier3 }}" - when: ansible_processor_vcpus < llm_tier3_cpu - or ansible_memtotal_mb < llm_tier3_ram - - - name: Workstation | Linux | Software | ZeroClaw | Facts | Merge | tier4 - ansible.builtin.set_fact: - llm_installs: "{{ llm_installs + llm_tier4 }}" - when: ansible_processor_vcpus >= llm_tier4_cpu - and ansible_memtotal_mb >= llm_tier4_ram - - - name: Workstation | Linux | Software | ZeroClaw | Facts | Merge | tier4 | Uninstalls - ansible.builtin.set_fact: - llm_removals: "{{ llm_removals + llm_tier4 }}" - when: ansible_processor_vcpus < llm_tier4_cpu - or ansible_memtotal_mb < llm_tier4_ram - - - name: Workstation | Linux | Software | ZeroClaw | Facts | Merge | tier5 - ansible.builtin.set_fact: - llm_installs: "{{ llm_installs + llm_tier5 }}" - when: ansible_processor_vcpus >= llm_tier5_cpu - and ansible_memtotal_mb >= llm_tier5_ram - - - name: Workstation | Linux | Software | ZeroClaw | Facts | Merge | tier5 | Uninstalls - ansible.builtin.set_fact: - llm_removals: "{{ llm_removals + llm_tier5 }}" - when: ansible_processor_vcpus < llm_tier5_cpu - or ansible_memtotal_mb < llm_tier5_ram - - - name: Workstation | Linux | Software | ZeroClaw | Facts | Merge | tier6 - ansible.builtin.set_fact: - llm_installs: "{{ llm_installs + llm_tier6 }}" - when: ansible_processor_vcpus >= llm_tier6_cpu - and ansible_memtotal_mb >= llm_tier6_ram - - - name: Workstation | Linux | Software | ZeroClaw | Facts | Merge | tier6 | Uninstalls - ansible.builtin.set_fact: - llm_removals: "{{ llm_removals + llm_tier6 }}" - when: ansible_processor_vcpus < llm_tier6_cpu - or ansible_memtotal_mb < llm_tier6_ram - - - name: Workstation | Linux | Software | ZeroClaw | Facts | Merge | tier7 - ansible.builtin.set_fact: - llm_installs: "{{ llm_installs + llm_tier7 }}" - when: ansible_processor_vcpus >= llm_tier7_cpu - and ansible_memtotal_mb >= llm_tier7_ram - - - name: Workstation | Linux | Software | ZeroClaw | Facts | Merge | tier7 | Uninstalls - ansible.builtin.set_fact: - llm_removals: "{{ llm_removals + llm_tier7 }}" - when: ansible_processor_vcpus < llm_tier7_cpu - or ansible_memtotal_mb < llm_tier7_ram - - - name: Workstation | Linux | Software | ZeroClaw | Facts | Merge | tier8 - ansible.builtin.set_fact: - llm_installs: "{{ llm_installs + llm_tier8 }}" - when: ansible_processor_vcpus >= llm_tier8_cpu - and ansible_memtotal_mb >= llm_tier8_ram - - - name: Workstation | Linux | Software | ZeroClaw | Facts | Merge | tier8 | Uninstalls - ansible.builtin.set_fact: - llm_removals: "{{ llm_removals + llm_tier8 }}" - when: ansible_processor_vcpus < llm_tier8_cpu - or ansible_memtotal_mb < llm_tier8_ram - - - name: Workstation | Linux | Software | ZeroClaw | Facts | Merge | tier9 - ansible.builtin.set_fact: - llm_installs: "{{ llm_installs + llm_tier9 }}" - when: ansible_processor_vcpus >= llm_tier9_cpu - and ansible_memtotal_mb >= llm_tier9_ram - - - name: Workstation | Linux | Software | ZeroClaw | Facts | Merge | tier9 | Uninstalls - ansible.builtin.set_fact: - llm_removals: "{{ llm_removals + llm_tier9 }}" - when: ansible_processor_vcpus < llm_tier9_cpu - or ansible_memtotal_mb < llm_tier9_ram + llm_installs: >- + {{ llm_choices | selectattr('size_mb', 'le', ansible_memtotal_mb) | list }} + llm_removals: >- + {{ llm_choices | selectattr('size_mb', 'gt', ansible_memtotal_mb) | list }} - name: Workstation | Linux | Software | ZeroClaw | Facts | Merge | Print ansible.builtin.debug: @@ -258,6 +130,7 @@ - ansible_processor_vcpus - ansible_memtotal_mb - llm_concurrency + - llm_parallel - llm_installs - llm_removals @@ -267,6 +140,7 @@ - "{{ zeroclaw }}" - "{{ ollama }}" - "{{ zerocode }}" + - "{{ qwen_code }}" state: present - name: Workstation | Linux | Software | ZeroClaw | runit @@ -300,13 +174,15 @@ # Allow pulling LLMs for use with ZeroClaw. exec 2>&1 export HOME={{ user_user.home }} - export OLLAMA_KEEP_ALIVE=20m # default 5m - export OLLAMA_REQUEST_TIMEOUT=3600 # default 300 (unconfirmed, not in the list of --help vars) + # Timeouts # export OLLAMA_LOAD_TIMEOUT=30m # default is 5m + export OLLAMA_REQUEST_TIMEOUT=3600 # default 300 (unconfirmed, not in the list of --help vars) + # Resource Usage # + export OLLAMA_KEEP_ALIVE=20m # default 5m export OLLAMA_MAX_LOADED_MODELS={{ llm_concurrency }} # default is 3 if using CPUs, or 3 * NumGPUs + export OLLAMA_NUM_PARALLEL={{ llm_parallel }} # default is 1 and applies per-model (unconfirmed) + export OLLAMA_CONTEXT_LENGTH=32000 # default is 4096, https://docs.ollama.com/faq#how-can-i-specify-the-context-window-size export OLLAMA_MAX_QUEUE=999 # default is 512 (unconfirmed) - export OLLAMA_NUM_PARALLEL={{ llm_concurrency }} # default is 1 and applies per-model (unconfirmed) - export OLLAMA_CONTEXT_LENGTH=999999 # default is 4096, https://docs.ollama.com/faq#how-can-i-specify-the-context-window-size exec chpst -u {{ user }} ollama serve dest: "{{ ollama_runit_script }}" mode: "0755"