- Posted on
- • Artificial Intelligence
Artificial Intelligence Backup Checklists
- Author
-
-
- User
- linuxbash
- Posts by this author
- Posts by this author
-
Artificial Intelligence Backup Checklists: A Bash-first Guide to Never Losing Your Models, Data, or Mind
If your GPU dies tonight or your cloud project gets accidentally deleted, how quickly can you rebuild your AI stack? In machine learning and LLM work, “the project” isn’t just code—it’s datasets, model weights, experiment metadata, prompts, feature stores, and the exact environment that produced your results. Without a solid, automatable backup checklist, you’re betting your research and product timelines on luck.
This guide gives you a practical, Bash-centric backup checklist for AI projects, with concrete scripts you can drop into your workflow. You’ll learn what to back up, how to store it securely, and how to automate verification and restores.
Why an AI-specific backup checklist?
AI artifacts are large, diverse, and volatile: datasets, pre-trained weights, fine-tuned checkpoints, vector indexes, and logs are all moving targets.
Reproducibility and compliance matter: you need to prove what data and config produced a model version, sometimes under regulation.
Time is money: recomputing models or re-labeling data is costly; losing experiment history is worse.
Security is non-negotiable: sensitive data and secrets demand encryption at rest and in transit.
The AI Backup Checklist (what to protect)
Use this inventory to define your backup scope:
Source and Infrastructure as Code:
gitrepos, CI/CD configs, IaC (Terraform/Ansible), notebooks.Datasets and Data Manifests: raw, processed, and split data; schema; data versions or manifests (hash lists).
Models and Artifacts: pre-trained weights, fine-tuned checkpoints, tokenizer files, embeddings, vector store snapshots.
Experiments and Metadata: hyperparameters, training configs, metrics, run logs (e.g., W&B), random seeds, commit hashes.
Environment and Dependencies:
requirements.txt,conda env export, container image references/Dockerfile, CUDA/cuDNN versions.Secrets and Access: do not store secrets in backups; store references to where they live (Vault/KMS). Keep backup encryption keys separate.
Orchestration and Infra Snapshots: job configs, SLURM specs, Kubernetes manifests, storage class definitions.
Tip: Keep a human-readable manifest at the root of each project that lists paths to all of the above. Back it up with everything else.
Tools you’ll use (install once)
We’ll lean on proven, scriptable tools:
rsync: fast local copies
restic: deduplicated, encrypted backups to local or object storage (S3, B2, etc.)
borgbackup: deduplicated backups over SSH/NAS
rclone: mirrors and moves data across clouds
jq: compose small manifests in JSON
Install them with your distro’s package manager:
- Debian/Ubuntu (apt):
sudo apt update
sudo apt install -y rsync rclone restic borgbackup jq
- Fedora/RHEL/CentOS Stream (dnf):
sudo dnf install -y rsync rclone restic borgbackup jq
- openSUSE (zypper):
sudo zypper refresh
sudo zypper install -y rsync rclone restic borgbackup jq
No extra package is required for systemd timers (present on modern distros).
1) Build your AI backup manifest (lightweight, provable)
Create a quick, reproducible manifest that captures versions, hashes, and environment. Run this at the start of each backup.
#!/usr/bin/env bash
set -euo pipefail
PROJECT_ROOT="${1:-$PWD}"
OUT_DIR="${PROJECT_ROOT}/.backup-meta"
mkdir -p "$OUT_DIR"
# Capture Python dependency state
if command -v python >/dev/null 2>&1 && python -c "import pkgutil" >/dev/null 2>&1; then
python -m pip freeze > "${OUT_DIR}/requirements.lock" || true
fi
# Conda env (if present)
if command -v conda >/dev/null 2>&1; then
conda env export > "${OUT_DIR}/conda-env.yaml" || true
fi
# Git state
if command -v git >/dev/null 2>&1 && [ -d "${PROJECT_ROOT}/.git" ]; then
git -C "$PROJECT_ROOT" rev-parse HEAD > "${OUT_DIR}/git-commit.txt" || true
git -C "$PROJECT_ROOT" status --porcelain=v1 > "${OUT_DIR}/git-status.txt" || true
git -C "$PROJECT_ROOT" remote -v > "${OUT_DIR}/git-remotes.txt" || true
fi
# Data manifest (hash a sample of large files to keep it fast)
find "$PROJECT_ROOT/data" -type f 2>/dev/null | head -n 200 | sort | xargs -r sha256sum > "${OUT_DIR}/data.sha256"
# Minimal machine info
uname -a > "${OUT_DIR}/system.txt" || true
nvidia-smi -L > "${OUT_DIR}/gpus.txt" 2>/dev/null || true
# JSON index for tooling
jq -n \
--arg time "$(date -Is)" \
--arg project "$PROJECT_ROOT" \
--arg commit "$(cat "${OUT_DIR}/git-commit.txt" 2>/dev/null || echo unknown)" \
'{generated_at:$time, project:$project, git_commit:$commit}' \
> "${OUT_DIR}/index.json"
What this gives you:
Fast-to-compare checksums of representative data
Exact dependency fingerprints
Git provenance to map models to code
2) Pick a storage pattern that won’t betray you
Follow 3-2-1:
3 copies of your data
2 different media (e.g., object storage and local disk/NAS)
1 offsite/immutable copy
Common patterns:
Primary encrypted restic repo in S3-compatible storage (S3, B2, MinIO)
Secondary borg repo on an SSH-accessible NAS
Optional local rsync mirror for quick restores
Security:
Use restic’s built-in encryption
Store encryption password in a root-only file on a separate host or secrets manager
For S3, enable Object Lock/Versioning if available to resist accidental deletion or ransomware
3) Script the backup (Bash + restic + rsync)
This script:
Builds the manifest
Backs up project directories to restic (S3 or local)
Keeps a local rsync mirror for fast restores
Applies exclude rules and retention
Runs health checks
#!/usr/bin/env bash
set -euo pipefail
# Required: set these environment variables ahead of time (export or a .env file sourced here)
# export RESTIC_REPOSITORY="s3:https://s3.us-east-1.amazonaws.com/my-bucket/ai-backups"
# export RESTIC_PASSWORD_FILE="$HOME/.config/restic/ai.pw" # chmod 600
# For S3-compatible: export AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION
PROJECTS=(
"$HOME/projects/llm-finetune"
"$HOME/projects/vision-model"
)
LOCAL_MIRROR="/mnt/backup-mirror/ai"
TAGS="ai,$(hostname -s)"
EXCLUDES=(
"--exclude" "**/__pycache__"
"--exclude" "**/.mypy_cache"
"--exclude" "**/.ruff_cache"
"--exclude" "**/.venv"
"--exclude" "**/.ipynb_checkpoints"
"--exclude" "**/wandb/tmp"
"--exclude" "**/*.tmp"
"--exclude" "**/*.log"
# Do not back up secrets files directly; store them in a vault.
"--exclude" "**/.env"
"--exclude" "**/*.pem"
"--exclude" "**/id_rsa*"
)
# Init repo if needed
restic snapshots >/dev/null 2>&1 || restic init
for P in "${PROJECTS[@]}"; do
[ -d "$P" ] || continue
echo ">> Preparing manifest for $P"
"$(dirname "$0")/ai-build-manifest.sh" "$P" || true
echo ">> Restic backing up $P"
restic backup "${EXCLUDES[@]}" --tag "$TAGS" "$P"
echo ">> Local mirror rsync for $P"
mkdir -p "$LOCAL_MIRROR"
rsync -aHAX --delete --info=stats1 \
--exclude '__pycache__' --exclude '.venv' --exclude '.ipynb_checkpoints' \
"$P/" "$LOCAL_MIRROR/$(basename "$P")/"
done
echo ">> Apply retention (7 daily, 4 weekly, 6 monthly)"
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
echo ">> Integrity check (lightweight)"
restic check --read-data-subset=1% || true
echo ">> Done"
Notes:
For a purely local setup, point RESTIC_REPOSITORY to a path like
/srv/restic/ai.For an SSH/NAS alternative, see the borg snippet below.
Optional: Borg over SSH/NAS
#!/usr/bin/env bash
set -euo pipefail
export BORG_REPO="ssh://user@nas.lan:22/volume/backups/ai"
export BORG_PASSPHRASE="$(cat $HOME/.config/borg/ai.pw)"
borg init --encryption=repokey-blake2 || true
borg create --stats --progress \
::'{hostname}-{now:%Y-%m-%d_%H-%M}' \
"$HOME/projects/llm-finetune" \
"$HOME/projects/vision-model" \
--exclude '**/.venv' --exclude '**/__pycache__' --exclude '**/.ipynb_checkpoints' \
--exclude '**/.env' --exclude '**/*.pem'
borg prune --keep-daily=7 --keep-weekly=4 --keep-monthly=6
borg check --verify-data --max-duration=120 || true
4) Automate and verify with systemd timers
Use user-level systemd units (no root needed). Save these files and enable.
~/.config/systemd/user/ai-backup.service
[Unit]
Description=AI project backup (restic + rsync)
[Service]
Type=oneshot
Environment=RESTIC_REPOSITORY=s3:https://s3.us-east-1.amazonaws.com/my-bucket/ai-backups
Environment=RESTIC_PASSWORD_FILE=%h/.config/restic/ai.pw
Environment=AWS_DEFAULT_REGION=us-east-1
# Expect AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to be in an env file:
EnvironmentFile=%h/.config/restic/aws.env
ExecStart=%h/bin/ai-backup.sh
~/.config/systemd/user/ai-backup.timer
[Unit]
Description=Run AI backup daily at 02:00 with jitter
[Timer]
OnCalendar=*-*-* 02:00:00
RandomizedDelaySec=1800
Persistent=true
[Install]
WantedBy=timers.target
Enable and start:
systemctl --user daemon-reload
systemctl --user enable --now ai-backup.timer
systemctl --user list-timers
Verification and alerts:
- Parse restic output and send to your alerting (email/Slack). Example with journalctl:
journalctl --user -u ai-backup.service -n 200 --no-pager
- Weekly deeper verification:
restic check --read-data-subset=10%
5) Practice restores (and document them)
A backup you’ve never restored is a hypothesis. Test often.
Restore the latest snapshot for a single project:
TARGET="$HOME/restore-test"
mkdir -p "$TARGET"
SNAP=$(restic snapshots --json | jq -r '.[-1].short_id')
restic restore "$SNAP" --target "$TARGET" --path "$HOME/projects/llm-finetune"
Sanity-check hashes against your manifest:
pushd "$TARGET/$HOME/projects/llm-finetune/.backup-meta" >/dev/null
sha256sum -c data.sha256 --ignore-missing || true
popd >/dev/null
Disaster drill: recover only what you need fast
- Pull a specific checkpoint or tokenizer file
restic restore latest --target "$TARGET" --include '*/checkpoints/epoch-3/*'
restic restore latest --target "$TARGET" --include '*/tokenizer.json'
Security tip:
- Keep
RESTIC_PASSWORD_FILEoff the same machine (or in a password manager/secret store). If you must keep a local copy, ensure strict perms:chmod 600.
Real-world examples
LLM fine-tuning project
- Back up: train/val JSONL, tokenizer files, final and intermediate checkpoints,
wandbrun summaries,training_args.json, your fine-tune script,requirements.lock, andgit-commit.txt. - Avoid: huge ephemeral batch logs and caches; capture a sample instead.
- Bonus: store the model card and evaluation report alongside the artifact.
- Back up: train/val JSONL, tokenizer files, final and intermediate checkpoints,
Vision model on-prem + NAS
- Primary: restic to B2/S3 with object lock enabled.
- Secondary: borg to office NAS over SSH.
- Restore drill: monthly random class from dataset and last month’s best checkpoint.
Compliance-conscious team
- Don’t back up raw PII; back up de-identification code + manifests of derived data.
- Keep key material in KMS/Vault, never in backups. Rotate regularly.
- Apply bucket policies/retention and log reads/writes for audits.
Common gotchas
Backing up
.venvinstead of environment lockfiles. Preferrequirements.lock,conda-env.yaml, and container image references.Not excluding secrets. Use a vault; add safe excludes.
Skipping verification. Schedule
restic checkand a quarterly restore drill.One copy only. Embrace 3-2-1 with at least one immutable/offsite copy.
Conclusion and next steps
Backups are boring—until they save weeks of compute and months of learning. Start now: 1) Copy the manifest and backup scripts into your repo. 2) Configure your restic repo and credentials; run a first full backup. 3) Enable the systemd timer and schedule a restore drill on your calendar.
Your models, data, and research deserve production-grade resilience. Ship your AI with a backup plan you trust.