| #!/usr/bin/env bash |
| set -Eeuo pipefail |
|
|
| script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" |
| release_name=Ling-3.0-Flash-CIRU-int4-Strix-native |
| export PATH="$HOME/.local/bin:$PATH" |
|
|
| usage() { |
| cat <<EOF |
| Install the CIRU Ling 3.0 Flash gfx1151 runtime. |
| |
| Human-guided install: |
| bash install.sh --interactive |
| |
| Non-interactive install for agents and automation: |
| bash install.sh --install-root PATH --model-path PATH [OPTIONS] |
| |
| Engine-only upgrade of an existing installation: |
| bash install.sh --upgrade --install-root PATH |
| |
| Options: |
| --interactive Ask for paths and optional actions. |
| --install-root PATH Runtime root; defaults to the current directory. |
| The vLLM environment is created at PATH/.venv. |
| PATH cannot contain whitespace or a colon because |
| the ROCr override is loaded through LD_PRELOAD. |
| --model-path PATH Exact checkpoint directory; defaults to |
| ./Ling-3.0-Flash-CIRU-int4-Strix-native. |
| --install-host-deps Run scripts/install-host-deps.sh (may use sudo). |
| --download-model Download the pinned checkpoint from this repository |
| to MODEL_PATH. Without this flag, a missing model does |
| not block the runtime installation. |
| The checkpoint is approximately 77 GB. |
| --upgrade Upgrade only the CIRU engine in an existing runtime. |
| Model weights and ling3-runtime.env are not touched. |
| --skip-build Validate/configure an already-built runtime. |
| --dry-run Print the commands and resolved paths without running them. |
| --print-env Print launch exports for the resolved paths and exit. |
| -h, --help Show this help. |
| |
| The installer writes PATH/ling3-runtime.env before downloads/builds. Agents can use: |
| source PATH/ling3-runtime.env |
| bash scripts/run-256k.sh |
| |
| Environment variables can always be supplied directly: |
| VENV=PATH/.venv MODEL_PATH=MODEL_PATH bash scripts/run-256k.sh |
| EOF |
| } |
|
|
| die() { |
| printf 'install.sh: %s\n' "$*" >&2 |
| exit 2 |
| } |
|
|
| absolute_path() { |
| local path="$1" |
| case "$path" in |
| '~') path="$HOME" ;; |
| [~]/*) path="$HOME/${path#\~/}" ;; |
| '$HOME') path="$HOME" ;; |
| '$HOME/'*) path="$HOME/${path#\$HOME/}" ;; |
| '${HOME}') path="$HOME" ;; |
| '${HOME}/'*) path="$HOME/${path#\$\{HOME\}/}" ;; |
| '$PWD') path="$PWD" ;; |
| '$PWD/'*) path="$PWD/${path#\$PWD/}" ;; |
| '${PWD}') path="$PWD" ;; |
| '${PWD}/'*) path="$PWD/${path#\$\{PWD\}/}" ;; |
| esac |
| case "$path" in |
| *'$'*) die "unexpanded shell variable in path: $path" ;; |
| esac |
| if command -v realpath >/dev/null 2>&1; then |
| realpath -m -- "$path" |
| elif [[ "$path" = /* ]]; then |
| printf '%s\n' "$path" |
| else |
| printf '%s/%s\n' "$PWD" "${path#./}" |
| fi |
| } |
|
|
| write_runtime_env() { |
| local temporary_file="$env_file.tmp.$$" |
| mkdir -p "$install_root" |
| { |
| printf '# Generated by %s/install.sh\n' "$script_dir" |
| printf 'export VENV=%q\n' "$venv" |
| printf 'export MODEL_PATH=%q\n' "$model_path" |
| } >"$temporary_file" |
| mv -f -- "$temporary_file" "$env_file" |
| } |
|
|
| prompt_value() { |
| local variable_name="$1" |
| local label="$2" |
| local default_value="$3" |
| local reply |
| read -r -p "$label [$default_value]: " reply |
| printf -v "$variable_name" '%s' "${reply:-$default_value}" |
| } |
|
|
| ask_yes_no() { |
| local label="$1" |
| local default_answer="$2" |
| local suffix reply |
| if [ "$default_answer" = yes ]; then |
| suffix='[Y/n]' |
| else |
| suffix='[y/N]' |
| fi |
| while true; do |
| read -r -p "$label $suffix: " reply |
| reply="${reply:-$default_answer}" |
| case "${reply,,}" in |
| y|yes) return 0 ;; |
| n|no) return 1 ;; |
| *) printf 'Please answer yes or no.\n' >&2 ;; |
| esac |
| done |
| } |
|
|
| interactive=0 |
| install_root= |
| model_path= |
| install_host_deps=0 |
| download_model=0 |
| build_runtime=1 |
| dry_run=0 |
| print_env=0 |
| upgrade=0 |
|
|
| if [ "$#" -eq 0 ]; then |
| usage |
| exit 0 |
| fi |
|
|
| while [ "$#" -gt 0 ]; do |
| case "$1" in |
| --interactive) |
| interactive=1 |
| shift |
| ;; |
| --install-root) |
| [ "$#" -ge 2 ] || die '--install-root requires a path' |
| [ -n "$2" ] || die '--install-root requires a non-empty path' |
| install_root="$2" |
| shift 2 |
| ;; |
| --model-path) |
| [ "$#" -ge 2 ] || die '--model-path requires a path' |
| [ -n "$2" ] || die '--model-path requires a non-empty path' |
| model_path="$2" |
| shift 2 |
| ;; |
| --install-host-deps) |
| install_host_deps=1 |
| shift |
| ;; |
| --download-model) |
| download_model=1 |
| shift |
| ;; |
| --upgrade) |
| upgrade=1 |
| shift |
| ;; |
| --skip-build) |
| build_runtime=0 |
| shift |
| ;; |
| --dry-run) |
| dry_run=1 |
| shift |
| ;; |
| --print-env) |
| print_env=1 |
| shift |
| ;; |
| -h|--help) |
| usage |
| exit 0 |
| ;; |
| *) |
| die "unknown option: $1" |
| ;; |
| esac |
| done |
|
|
| if [ "$upgrade" = 1 ]; then |
| [ -z "$model_path" ] || die '--model-path is not used with --upgrade' |
| [ "$download_model" = 0 ] || die '--download-model is not used with --upgrade' |
| [ "$build_runtime" = 1 ] || die '--skip-build is not used with --upgrade' |
| [ "$print_env" = 0 ] || die '--print-env is not used with --upgrade' |
| fi |
|
|
| if [ "$interactive" = 1 ]; then |
| [ -t 0 ] || die '--interactive requires a terminal; use explicit flags for automation' |
| prompt_value install_root 'Runtime install directory' "${install_root:-$PWD}" |
| if [ "$upgrade" != 1 ]; then |
| prompt_value model_path 'Ling checkpoint directory' \ |
| "${model_path:-$PWD/$release_name}" |
| fi |
| if ask_yes_no 'Run the distro host-dependency installer (may use sudo)?' no; then |
| install_host_deps=1 |
| fi |
| if [ "$upgrade" != 1 ] && [ ! -f "$model_path/config.json" ]; then |
| if ask_yes_no 'Checkpoint not found there. Download it from this repository (~77 GB)?' no; then |
| download_model=1 |
| fi |
| fi |
| fi |
|
|
| install_root="$(absolute_path "${install_root:-$PWD}")" |
| case "$install_root" in |
| *[[:space:]:]*) |
| die "install root cannot contain whitespace or ':' because ROCr is loaded through LD_PRELOAD: $install_root" |
| ;; |
| esac |
| venv="$install_root/.venv" |
| env_file="$install_root/ling3-runtime.env" |
| if [ "$upgrade" != 1 ]; then |
| model_path="$(absolute_path "${model_path:-$PWD/$release_name}")" |
| fi |
|
|
| if [ "$print_env" = 1 ]; then |
| printf 'export VENV=%q\n' "$venv" |
| printf 'export MODEL_PATH=%q\n' "$model_path" |
| exit 0 |
| fi |
|
|
| if [ "$upgrade" = 1 ]; then |
| printf 'CIRU Ling engine-only upgrade\n' |
| printf ' package: %s\n install root: %s\n venv: %s\n' \ |
| "$script_dir" "$install_root" "$venv" |
| printf ' host dependencies: %s\n model files: preserved\n' "$install_host_deps" |
| else |
| printf 'CIRU Ling runtime installation\n' |
| printf ' package: %s\n install root: %s\n venv: %s\n model: %s\n' \ |
| "$script_dir" "$install_root" "$venv" "$model_path" |
| printf ' host dependencies: %s\n download model: %s\n build runtime: %s\n' \ |
| "$install_host_deps" "$download_model" "$build_runtime" |
| fi |
|
|
| if [ "$interactive" = 1 ] && ! ask_yes_no 'Continue with these settings?' yes; then |
| printf 'Installation cancelled.\n' |
| exit 0 |
| fi |
|
|
| if [ "$dry_run" = 1 ]; then |
| if [ "$install_host_deps" = 1 ]; then |
| printf 'DRY RUN: bash %q\n' "$script_dir/scripts/install-host-deps.sh" |
| fi |
| if [ "$upgrade" = 1 ]; then |
| printf 'DRY RUN: validate %q and preserve model files/configuration\n' "$venv" |
| printf 'DRY RUN: bash %q %q\n' \ |
| "$script_dir/scripts/install-rocr-idle-fix.sh" "$install_root" |
| exit 0 |
| fi |
| if [ "$download_model" = 1 ]; then |
| printf 'DRY RUN: bash %q --model-path %q\n' \ |
| "$script_dir/scripts/download-model.sh" "$model_path" |
| fi |
| if [ "$build_runtime" = 1 ]; then |
| printf 'DRY RUN: bash %q %q\n' \ |
| "$script_dir/scripts/build-vllm-gfx1151.sh" "$install_root" |
| fi |
| printf 'DRY RUN: bash %q %q\n' \ |
| "$script_dir/scripts/install-rocr-idle-fix.sh" "$install_root" |
| printf 'DRY RUN: write %q\n' "$env_file" |
| exit 0 |
| fi |
|
|
| if [ "$upgrade" = 1 ]; then |
| [ -x "$venv/bin/python" ] || \ |
| die "existing CIRU runtime is missing Python: $venv/bin/python" |
| [ -x "$venv/bin/vllm" ] || \ |
| die "existing CIRU runtime is missing vLLM: $venv/bin/vllm" |
| if [ "$install_host_deps" = 1 ]; then |
| bash "$script_dir/scripts/install-host-deps.sh" |
| fi |
| bash "$script_dir/scripts/install-rocr-idle-fix.sh" "$install_root" |
| printf '\nEngine upgrade complete. Model files and ling3-runtime.env were unchanged.\n' |
| printf 'Restart the CIRU launcher or service to load the corrected ROCr runtime.\n' |
| printf 'Emergency rollback: set CIRU_DISABLE_ROCR_IDLE_FIX=1 before launching.\n' |
| exit 0 |
| fi |
|
|
| |
| |
| |
| write_runtime_env |
| printf 'Prepared environment file: %s\n' "$env_file" |
|
|
| if [ "$download_model" != 1 ] && [ ! -f "$model_path/config.json" ]; then |
| printf 'Model download skipped; the runtime will be installed without weights.\n' |
| printf 'Expected future model path: %s\n' "$model_path" |
| fi |
|
|
| if [ "$install_host_deps" = 1 ]; then |
| bash "$script_dir/scripts/install-host-deps.sh" |
| fi |
|
|
| if [ "$download_model" = 1 ]; then |
| bash "$script_dir/scripts/download-model.sh" --model-path "$model_path" |
| fi |
|
|
| if [ "$build_runtime" = 1 ]; then |
| bash "$script_dir/scripts/build-vllm-gfx1151.sh" "$install_root" |
| fi |
| bash "$script_dir/scripts/install-rocr-idle-fix.sh" "$install_root" |
|
|
| [ -x "$venv/bin/python" ] || die "runtime Python is missing after installation: $venv/bin/python" |
| [ -x "$venv/bin/vllm" ] || die "vLLM launcher is missing after installation: $venv/bin/vllm" |
| if [ -f "$model_path/config.json" ]; then |
| model_ready=1 |
| elif [ "$download_model" = 1 ]; then |
| die "model download completed without the expected config: $model_path/config.json" |
| else |
| model_ready=0 |
| fi |
|
|
| printf '\nInstallation complete.\n' |
| printf 'Environment file: %s\n\n' "$env_file" |
| if [ "$model_ready" = 1 ]; then |
| printf 'Launch the native 256K profile:\n' |
| printf ' source %q\n bash %q\n\n' "$env_file" "$script_dir/scripts/run-256k.sh" |
| else |
| printf 'The optional model download was skipped. Download it later with:\n' |
| printf ' bash %q --model-path %q\n\n' \ |
| "$script_dir/scripts/download-model.sh" "$model_path" |
| printf 'Then launch with:\n' |
| printf ' source %q\n bash %q\n\n' "$env_file" "$script_dir/scripts/run-256k.sh" |
| fi |
| printf 'For agents or automation:\n' |
| printf ' export VENV=%q\n export MODEL_PATH=%q\n' "$venv" "$model_path" |
| if [ "$model_ready" = 1 ]; then |
| printf ' bash %q\n' "$script_dir/scripts/run-256k.sh" |
| else |
| printf ' # Provide the checkpoint before running %q\n' "$script_dir/scripts/run-256k.sh" |
| fi |
|
|