This commit is contained in:
c4ch3c4d3
2026-04-01 17:09:27 -06:00
parent a2d4f9d86d
commit 30b919c0b9
7 changed files with 328 additions and 89 deletions
+38
View File
@@ -98,6 +98,44 @@ courseware_wsl_cuda_installer_filename: "cuda-repo-wsl-ubuntu-13-2-local_13.2.0-
courseware_wsl_cuda_installer_local_path: "/tmp/cuda-repo-wsl-ubuntu-13-2-local_13.2.0-1_amd64.deb"
courseware_wsl_cuda_repo_dir: "/var/cuda-repo-wsl-ubuntu-13-2-local"
courseware_wsl_cuda_toolkit_package: "cuda-toolkit-13-2"
courseware_native_cuda_keyring_version: "1.1-1"
courseware_native_cuda_repo_slug: >-
{{
('debian' ~ ansible_distribution_major_version)
if ansible_distribution == 'Debian'
else (
'ubuntu' ~ (ansible_distribution_version | replace('.', ''))
if ansible_distribution == 'Ubuntu'
else ''
)
}}
courseware_native_cuda_repo_arch: >-
{{
'x86_64'
if ansible_architecture in ['x86_64', 'amd64']
else (
'arm64'
if ansible_architecture in ['arm64', 'aarch64']
else ''
)
}}
courseware_native_cuda_repo_supported: >-
{{
(
ansible_distribution == 'Debian'
and ansible_distribution_major_version in ['12', '13']
and courseware_native_cuda_repo_arch == 'x86_64'
)
or
(
ansible_distribution == 'Ubuntu'
and (ansible_distribution_version | replace('.', '')) in ['2204', '2404']
and courseware_native_cuda_repo_arch in ['x86_64', 'arm64']
)
}}
courseware_native_cuda_keyring_url: "https://developer.download.nvidia.com/compute/cuda/repos/{{ courseware_native_cuda_repo_slug }}/{{ courseware_native_cuda_repo_arch }}/cuda-keyring_{{ courseware_native_cuda_keyring_version }}_all.deb"
courseware_native_cuda_keyring_local_path: "{{ courseware_downloads_dir }}/cuda-keyring-{{ courseware_native_cuda_repo_slug }}-{{ courseware_native_cuda_repo_arch }}.deb"
courseware_native_cuda_toolkit_package: "cuda-toolkit"
courseware_unsloth_installer_url: "https://unsloth.ai/install.sh"
courseware_unsloth_installer_path: "{{ courseware_downloads_dir }}/unsloth-install.sh"
courseware_unsloth_python_version: "3.12"
+71 -12
View File
@@ -12,6 +12,22 @@
failed_when: false
when: ansible_system == "Linux"
- name: Check for CUDA compiler in standard install locations
shell: |
for candidate in /usr/local/cuda/bin/nvcc /usr/local/cuda-*/bin/nvcc; do
if [ -x "$candidate" ]; then
printf '%s\n' "$candidate"
exit 0
fi
done
exit 1
args:
executable: /bin/bash
register: courseware_llama_nvcc_fallback
changed_when: false
failed_when: false
when: ansible_system == "Linux"
- name: Check for CUDA runtime header on Linux
stat:
path: "{{ item }}"
@@ -48,24 +64,63 @@
ls /usr/local/cuda/include/cuda_runtime.h
when:
- ansible_system == "Linux"
- courseware_llama_nvcc.rc != 0 or (courseware_llama_cuda_headers.results | selectattr('stat.exists', 'equalto', true) | list | length == 0)
- courseware_llama_nvcc.rc != 0
- courseware_llama_nvcc_fallback.rc != 0
- (courseware_llama_cuda_headers.results | selectattr('stat.exists', 'equalto', true) | list | length == 0)
- name: Set CUDA compiler path for llama.cpp builds
set_fact:
courseware_llama_cuda_compiler: "{{ (courseware_llama_nvcc.stdout | trim) if courseware_llama_nvcc.rc == 0 else (courseware_llama_nvcc_fallback.stdout | trim) }}"
courseware_llama_cuda_bin_dir: "{{ ((courseware_llama_nvcc.stdout | trim) if courseware_llama_nvcc.rc == 0 else (courseware_llama_nvcc_fallback.stdout | trim)) | dirname }}"
when:
- ansible_system == "Linux"
- courseware_llama_nvcc.rc == 0 or courseware_llama_nvcc_fallback.rc == 0
- name: Set llama.cpp backend flag
set_fact:
courseware_llama_backend_flag: "{{ '-DGGML_METAL=ON' if ansible_system == 'Darwin' else '-DGGML_CUDA=ON' }}"
- name: Set llama.cpp build parallelism
set_fact:
courseware_llama_build_jobs: >-
{{
[
1,
[
ansible_processor_vcpus | default(ansible_processor_nproc | default(1)) | int,
((ansible_memtotal_mb | int) // 8192) | int,
4
] | min
] | max
}}
- name: Build llama.cpp CMake configure arguments
set_fact:
courseware_llama_cmake_configure_argv: >-
{{
[
'cmake',
'-S',
courseware_repos_dir ~ '/llama.cpp',
'-B',
courseware_repos_dir ~ '/llama.cpp/build',
'-DCMAKE_BUILD_TYPE=Release',
courseware_llama_backend_flag
]
+
(
['-DCMAKE_CUDA_COMPILER=' ~ courseware_llama_cuda_compiler]
if ansible_system == 'Linux' and (courseware_llama_cuda_compiler | default('') | length > 0)
else []
)
}}
- name: Configure llama.cpp
command:
argv:
- cmake
- -S
- "{{ courseware_repos_dir }}/llama.cpp"
- -B
- "{{ courseware_repos_dir }}/llama.cpp/build"
- -DCMAKE_BUILD_TYPE=Release
- "{{ courseware_llama_backend_flag }}"
args:
creates: "{{ courseware_repos_dir }}/llama.cpp/build/CMakeCache.txt"
argv: "{{ courseware_llama_cmake_configure_argv }}"
environment:
PATH: "{{ (courseware_llama_cuda_bin_dir ~ ':' ~ ansible_env.PATH) if ansible_system == 'Linux' and (courseware_llama_cuda_bin_dir | default('') | length > 0) else ansible_env.PATH }}"
CUDACXX: "{{ courseware_llama_cuda_compiler | default(omit) }}"
- name: Build llama.cpp tools
command:
@@ -73,12 +128,16 @@
- cmake
- --build
- "{{ courseware_repos_dir }}/llama.cpp/build"
- --parallel
- "{{ courseware_llama_build_jobs }}"
- --target
- llama-cli
- llama-quantize
- llama-perplexity
- llama-server
- -j
environment:
PATH: "{{ (courseware_llama_cuda_bin_dir ~ ':' ~ ansible_env.PATH) if ansible_system == 'Linux' and (courseware_llama_cuda_bin_dir | default('') | length > 0) else ansible_env.PATH }}"
CUDACXX: "{{ courseware_llama_cuda_compiler | default(omit) }}"
- name: Check system PATH slots for llama.cpp tools
stat:
+114 -19
View File
@@ -1,7 +1,6 @@
- name: Install Debian/Ubuntu prerequisites
become: true
apt:
name:
- name: Define Debian/Ubuntu prerequisite packages
set_fact:
courseware_linux_prereq_packages:
- build-essential
- ca-certificates
- cmake
@@ -18,8 +17,47 @@
- python3-venv
- unzip
- zstd
state: present
update_cache: true
- name: Install Debian/Ubuntu prerequisites
block:
- name: Install Debian/Ubuntu prerequisite packages
become: true
apt:
name: "{{ courseware_linux_prereq_packages }}"
state: present
update_cache: true
rescue:
- name: Repair interrupted dpkg state before retrying prerequisites
become: true
command:
argv:
- dpkg
- --configure
- -a
register: courseware_dpkg_repair
changed_when: false
failed_when: false
- name: Repair broken apt dependencies before retrying prerequisites
become: true
command:
argv:
- apt-get
- -y
- --fix-broken
- install
environment:
DEBIAN_FRONTEND: noninteractive
register: courseware_apt_fix_broken
changed_when: >-
'0 upgraded, 0 newly installed, 0 to remove' not in courseware_apt_fix_broken.stdout
- name: Retry Debian/Ubuntu prerequisite package install
become: true
apt:
name: "{{ courseware_linux_prereq_packages }}"
state: present
update_cache: true
- name: Query CUDA toolkit apt candidate
command: apt-cache policy nvidia-cuda-toolkit
@@ -66,31 +104,88 @@
nvcc --version
ls /usr/local/cuda/include/cuda_runtime.h
when:
- not courseware_is_wsl
- courseware_host_profile == "native-debian-ubuntu"
- courseware_cuda_toolkit_package_available
- courseware_nvcc_check.rc != 0
- not courseware_cuda_toolkit_ready
- name: Fail with CUDA toolkit guidance when no apt candidate exists
- name: Fail when native CUDA network repository bootstrap is unsupported
fail:
msg: |
CUDA Toolkit is not available from this distro's current apt sources.
This native {{ ansible_distribution }} {{ ansible_distribution_version }} host does not match the CUDA network-repository variants this installer knows how to bootstrap automatically.
This installer needs the Linux-side CUDA toolkit for llama.cpp, not just a working `nvidia-smi`.
Supported native CUDA repo bootstrap targets currently match NVIDIA's documented Debian/Ubuntu paths:
- Debian 12 and Debian 13 on x86_64
- Ubuntu 22.04 and Ubuntu 24.04 on x86_64 or arm64
On WSL this usually means:
- Windows side: the NVIDIA driver is installed correctly
- Linux side: the CUDA toolkit repository is still missing
Add NVIDIA's CUDA repository for your Debian/Ubuntu release, install the toolkit, then rerun:
bash deploy-courseware.sh
Install the Linux-side CUDA toolkit manually for this host, then rerun:
./labctl up
Verify with:
nvcc --version
ls /usr/local/cuda/include/cuda_runtime.h
when:
- not courseware_is_wsl
- courseware_host_profile == "native-debian-ubuntu"
- not courseware_cuda_toolkit_package_available
- courseware_nvcc_check.rc != 0
- not courseware_cuda_toolkit_ready
- not courseware_native_cuda_repo_supported
- name: Bootstrap NVIDIA CUDA network repository for native Debian/Ubuntu
block:
- name: Download NVIDIA CUDA keyring package
get_url:
url: "{{ courseware_native_cuda_keyring_url }}"
dest: "{{ courseware_native_cuda_keyring_local_path }}"
mode: "0644"
force: false
- name: Install NVIDIA CUDA keyring package
become: true
apt:
deb: "{{ courseware_native_cuda_keyring_local_path }}"
state: present
- name: Install CUDA toolkit from NVIDIA network repository
become: true
apt:
name: "{{ courseware_native_cuda_toolkit_package }}"
state: present
update_cache: true
rescue:
- name: Repair interrupted dpkg state before retrying CUDA repository install
become: true
command:
argv:
- dpkg
- --configure
- -a
changed_when: false
failed_when: false
- name: Repair broken apt dependencies before retrying CUDA repository install
become: true
command:
argv:
- apt-get
- -y
- --fix-broken
- install
environment:
DEBIAN_FRONTEND: noninteractive
register: courseware_cuda_repo_fix_broken
changed_when: >-
'0 upgraded, 0 newly installed, 0 to remove' not in courseware_cuda_repo_fix_broken.stdout
- name: Retry CUDA toolkit install from NVIDIA network repository
become: true
apt:
name: "{{ courseware_native_cuda_toolkit_package }}"
state: present
update_cache: true
when:
- courseware_host_profile == "native-debian-ubuntu"
- not courseware_cuda_toolkit_package_available
- not courseware_cuda_toolkit_ready
- courseware_native_cuda_repo_supported
- name: Check for Ollama binary
command: which ollama
+47 -41
View File
@@ -1,6 +1,10 @@
- name: Detect WSL
- name: Classify supported host profile
set_fact:
courseware_is_macos: "{{ ansible_system == 'Darwin' }}"
courseware_is_linux: "{{ ansible_system == 'Linux' }}"
courseware_is_wsl: "{{ 'microsoft' in ansible_kernel | lower or 'wsl' in ansible_kernel | lower }}"
courseware_is_native_linux: "{{ ansible_system == 'Linux' and not ('microsoft' in ansible_kernel | lower or 'wsl' in ansible_kernel | lower) }}"
courseware_host_profile: "{{ 'macos' if ansible_system == 'Darwin' else ('wsl' if ('microsoft' in ansible_kernel | lower or 'wsl' in ansible_kernel | lower) else ('native-debian-ubuntu' if ansible_system == 'Linux' and ansible_os_family == 'Debian' else 'unsupported')) }}"
- name: Fail on unsupported operating systems
fail:
@@ -52,7 +56,7 @@
fail:
msg: "This installer currently supports Debian and Ubuntu only."
when:
- ansible_system == "Linux"
- courseware_is_linux
- ansible_os_family != "Debian"
- name: Query NVIDIA GPU memory
@@ -60,27 +64,27 @@
register: courseware_gpu_memory
changed_when: false
failed_when: false
when: ansible_system == "Linux"
when: courseware_is_linux
- name: Query NVIDIA GPU names
command: nvidia-smi --query-gpu=name --format=csv,noheader
register: courseware_gpu_names
changed_when: false
failed_when: false
when: ansible_system == "Linux"
when: courseware_is_linux
- name: Fail when no supported NVIDIA GPU is visible
fail:
msg: "Linux/WSL requires an NVIDIA GPU visible to nvidia-smi."
when:
- ansible_system == "Linux"
- courseware_is_linux
- courseware_gpu_memory.rc != 0
- name: Fail when GPU VRAM is below baseline
fail:
msg: "This build assumes at least 8 GB of VRAM on Linux/WSL."
when:
- ansible_system == "Linux"
- courseware_is_linux
- (courseware_gpu_memory.stdout_lines | map('int') | max) < 8192
- name: Check for CUDA compiler on Linux
@@ -88,7 +92,23 @@
register: courseware_preflight_nvcc
changed_when: false
failed_when: false
when: ansible_system == "Linux"
when: courseware_is_linux
- name: Check for CUDA compiler in standard install locations
shell: |
for candidate in /usr/local/cuda/bin/nvcc /usr/local/cuda-*/bin/nvcc; do
if [ -x "$candidate" ]; then
printf '%s\n' "$candidate"
exit 0
fi
done
exit 1
args:
executable: /bin/bash
register: courseware_preflight_nvcc_fallback
changed_when: false
failed_when: false
when: courseware_is_linux
- name: Check for CUDA runtime header on Linux
stat:
@@ -97,16 +117,17 @@
- /usr/local/cuda/include/cuda_runtime.h
- /usr/include/cuda_runtime.h
register: courseware_preflight_cuda_headers
when: ansible_system == "Linux"
when: courseware_is_linux
- name: Set CUDA toolkit readiness
set_fact:
courseware_cuda_toolkit_ready: >-
{{
courseware_preflight_nvcc.rc == 0
or courseware_preflight_nvcc_fallback.rc == 0
or (courseware_preflight_cuda_headers.results | selectattr('stat.exists', 'equalto', true) | list | length > 0)
}}
when: ansible_system == "Linux"
when: courseware_is_linux
- name: Query distro CUDA toolkit apt candidate
command: apt-cache policy nvidia-cuda-toolkit
@@ -114,7 +135,7 @@
changed_when: false
failed_when: false
when:
- ansible_system == "Linux"
- courseware_is_linux
- ansible_os_family == "Debian"
- name: Set distro CUDA toolkit package availability
@@ -125,15 +146,14 @@
and 'Candidate: (none)' not in courseware_preflight_cuda_toolkit_policy.stdout
}}
when:
- ansible_system == "Linux"
- courseware_is_linux
- ansible_os_family == "Debian"
- name: Fail when automatic WSL CUDA bootstrap is unsupported
fail:
msg: "Automatic CUDA bootstrap currently supports Ubuntu x86_64 on WSL only. For other WSL distros, install the CUDA toolkit manually before rerunning."
when:
- ansible_system == "Linux"
- courseware_is_wsl
- courseware_host_profile == "wsl"
- not courseware_cuda_toolkit_ready
- ansible_distribution != "Ubuntu" or ansible_architecture not in ["x86_64", "amd64"]
@@ -144,8 +164,7 @@
state: present
update_cache: true
when:
- ansible_system == "Linux"
- courseware_is_wsl
- courseware_host_profile == "wsl"
- not courseware_cuda_toolkit_ready
- ansible_distribution == "Ubuntu"
- ansible_architecture in ["x86_64", "amd64"]
@@ -157,8 +176,7 @@
changed_when: false
failed_when: false
when:
- ansible_system == "Linux"
- courseware_is_wsl
- courseware_host_profile == "wsl"
- not courseware_cuda_toolkit_ready
- ansible_distribution == "Ubuntu"
- ansible_architecture in ["x86_64", "amd64"]
@@ -172,8 +190,7 @@
- /usr/include/cuda_runtime.h
register: courseware_preflight_cuda_headers_after_distro_install
when:
- ansible_system == "Linux"
- courseware_is_wsl
- courseware_host_profile == "wsl"
- not courseware_cuda_toolkit_ready
- ansible_distribution == "Ubuntu"
- ansible_architecture in ["x86_64", "amd64"]
@@ -187,8 +204,7 @@
or (courseware_preflight_cuda_headers_after_distro_install.results | selectattr('stat.exists', 'equalto', true) | list | length > 0)
}}
when:
- ansible_system == "Linux"
- courseware_is_wsl
- courseware_host_profile == "wsl"
- not courseware_cuda_toolkit_ready
- ansible_distribution == "Ubuntu"
- ansible_architecture in ["x86_64", "amd64"]
@@ -201,8 +217,7 @@
changed_when: courseware_wsl_cuda_apt_key_delete.rc == 0
failed_when: false
when:
- ansible_system == "Linux"
- courseware_is_wsl
- courseware_host_profile == "wsl"
- not courseware_cuda_toolkit_ready
- ansible_distribution == "Ubuntu"
- ansible_architecture in ["x86_64", "amd64"]
@@ -215,8 +230,7 @@
mode: "0644"
force: true
when:
- ansible_system == "Linux"
- courseware_is_wsl
- courseware_host_profile == "wsl"
- not courseware_cuda_toolkit_ready
- ansible_distribution == "Ubuntu"
- ansible_architecture in ["x86_64", "amd64"]
@@ -228,8 +242,7 @@
mode: "0644"
force: false
when:
- ansible_system == "Linux"
- courseware_is_wsl
- courseware_host_profile == "wsl"
- not courseware_cuda_toolkit_ready
- ansible_distribution == "Ubuntu"
- ansible_architecture in ["x86_64", "amd64"]
@@ -240,8 +253,7 @@
deb: "{{ courseware_wsl_cuda_installer_local_path }}"
state: present
when:
- ansible_system == "Linux"
- courseware_is_wsl
- courseware_host_profile == "wsl"
- not courseware_cuda_toolkit_ready
- ansible_distribution == "Ubuntu"
- ansible_architecture in ["x86_64", "amd64"]
@@ -254,8 +266,7 @@
file_type: file
register: courseware_wsl_cuda_keyring
when:
- ansible_system == "Linux"
- courseware_is_wsl
- courseware_host_profile == "wsl"
- not courseware_cuda_toolkit_ready
- ansible_distribution == "Ubuntu"
- ansible_architecture in ["x86_64", "amd64"]
@@ -264,8 +275,7 @@
fail:
msg: "The NVIDIA WSL CUDA repository package was installed, but its keyring file was not found under {{ courseware_wsl_cuda_repo_dir }}."
when:
- ansible_system == "Linux"
- courseware_is_wsl
- courseware_host_profile == "wsl"
- not courseware_cuda_toolkit_ready
- ansible_distribution == "Ubuntu"
- ansible_architecture in ["x86_64", "amd64"]
@@ -279,8 +289,7 @@
remote_src: true
mode: "0644"
when:
- ansible_system == "Linux"
- courseware_is_wsl
- courseware_host_profile == "wsl"
- not courseware_cuda_toolkit_ready
- ansible_distribution == "Ubuntu"
- ansible_architecture in ["x86_64", "amd64"]
@@ -293,8 +302,7 @@
state: present
update_cache: true
when:
- ansible_system == "Linux"
- courseware_is_wsl
- courseware_host_profile == "wsl"
- not courseware_cuda_toolkit_ready
- ansible_distribution == "Ubuntu"
- ansible_architecture in ["x86_64", "amd64"]
@@ -305,8 +313,7 @@
changed_when: false
failed_when: false
when:
- ansible_system == "Linux"
- courseware_is_wsl
- courseware_host_profile == "wsl"
- not courseware_cuda_toolkit_ready
- ansible_distribution == "Ubuntu"
- ansible_architecture in ["x86_64", "amd64"]
@@ -315,8 +322,7 @@
fail:
msg: "The NVIDIA WSL CUDA toolkit install completed, but `nvcc` is still missing. Verify the repository package and rerun the installer."
when:
- ansible_system == "Linux"
- courseware_is_wsl
- courseware_host_profile == "wsl"
- not courseware_cuda_toolkit_ready
- ansible_distribution == "Ubuntu"
- ansible_architecture in ["x86_64", "amd64"]
+1
View File
@@ -1,3 +1,4 @@
COURSEWARE_HOST_PROFILE="{{ courseware_host_profile | trim }}"
COURSEWARE_ROOT="{{ courseware_root }}"
COURSEWARE_STATE_DIR="{{ courseware_state_dir }}"
COURSEWARE_BIND_HOST="{{ courseware_bind_host }}"