[GH-ISSUE #15484] How to backup and restore MLX Models? #87588

Closed
opened 2026-05-10 06:05:45 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @JoeLoginIsAlreadyTaken on GitHub (Apr 10, 2026).
Original GitHub issue: https://github.com/ollama/ollama/issues/15484

I have only limited flash storage on the Mac. So i sometimes have to remove one model to test an other.
To not pull over and over again (which needs hours) I back up to model data to an external drive.

In the past I used "ollama show --modelfile ..." to generate a modelfile and get the list of the blobs which need to be copied. This worked well.

This approach doesn't work for the MLX models, as the generated modelfile doesn't contain the blobs anymore.
I could find out the relevant blobs from the json. But how to re-import this model the models?

I am grateful for any tips.

Originally created by @JoeLoginIsAlreadyTaken on GitHub (Apr 10, 2026). Original GitHub issue: https://github.com/ollama/ollama/issues/15484 I have only limited flash storage on the Mac. So i sometimes have to remove one model to test an other. To not pull over and over again (which needs hours) I back up to model data to an external drive. In the past I used "ollama show --modelfile ..." to generate a modelfile and get the list of the blobs which need to be copied. This worked well. This approach doesn't work for the MLX models, as the generated modelfile doesn't contain the blobs anymore. I could find out the relevant blobs from the json. But how to re-import this model the models? I am grateful for any tips.
Author
Owner

@rick-github commented on GitHub (Apr 11, 2026):

Create a zip file of the blobs. To restore the model, cd to the ollama model directory and extract the zip.

#!/bin/bash

die(){
  echo "$1"
  exit 1
}

_=$(command -v jq) || die "Need jq"
_=$(command -v zip) || die "Need zip"

! PARSED=$(getopt --options=n0123456789 --longoptions=dryrun --name "$0" -- "$@")
[[ ${PIPESTATUS[0]} -ne 0 ]] && die "Parsing failed"
eval set -- "$PARSED"

DRYRUN=
store=0

while true; do
  case "$1" in
    -n|--dryrun)
      DRYRUN=echo
      shift
      ;;
    -[0-9])
      store=${1#-}
      shift
      ;;
    --)
      shift
      break
      ;;
    *)
      die "Parsing failed"
      ;;
  esac
done

zip_model() {
  model="$1"
  registry=registry.ollama.ai
  library=library
  name="${model%:*}" ; name="${name##*/}"
  [[ "$model" = */*/* ]] && registry="${model%%/*}"
  [[ "$model" = */* ]] && { library="${model%/*}" ; library="${library#*/}" ; }
  [[ "$model" = *:* ]] && tag="${model##*:}" || tag=latest

  OLLAMA_MODELS=${OLLAMA_MODELS-/usr/share/ollama/.ollama/models}

  [ ! -d $OLLAMA_MODELS ] && die "Couldn't find OLLAMA_MODELS ($OLLAMA_MODELS)"
  [ ! -d "$OLLAMA_MODELS/blobs" -o ! -d "$OLLAMA_MODELS/manifests" ] && die "blobs or manifests directory not found"

  manifest="manifests/$registry/$library/$name/$tag"

  [ ! -f "$OLLAMA_MODELS/$manifest" ] && die "Model $model not found at $manifest"

  blobs=$(jq -r '[.config.digest, (.layers[].digest)]|.[]' "$OLLAMA_MODELS/$manifest" | sed -e 's@^sha256:@blobs/sha256-@')

  dst="$(realpath ./${model//\//-})".zip
  (cd "$OLLAMA_MODELS" && $DRYRUN zip -$store $dst $manifest $blobs)
}

for model in $* ; do
  zip_model $model
done
<!-- gh-comment-id:4230238371 --> @rick-github commented on GitHub (Apr 11, 2026): Create a zip file of the blobs. To restore the model, cd to the ollama model directory and extract the zip. ```sh #!/bin/bash die(){ echo "$1" exit 1 } _=$(command -v jq) || die "Need jq" _=$(command -v zip) || die "Need zip" ! PARSED=$(getopt --options=n0123456789 --longoptions=dryrun --name "$0" -- "$@") [[ ${PIPESTATUS[0]} -ne 0 ]] && die "Parsing failed" eval set -- "$PARSED" DRYRUN= store=0 while true; do case "$1" in -n|--dryrun) DRYRUN=echo shift ;; -[0-9]) store=${1#-} shift ;; --) shift break ;; *) die "Parsing failed" ;; esac done zip_model() { model="$1" registry=registry.ollama.ai library=library name="${model%:*}" ; name="${name##*/}" [[ "$model" = */*/* ]] && registry="${model%%/*}" [[ "$model" = */* ]] && { library="${model%/*}" ; library="${library#*/}" ; } [[ "$model" = *:* ]] && tag="${model##*:}" || tag=latest OLLAMA_MODELS=${OLLAMA_MODELS-/usr/share/ollama/.ollama/models} [ ! -d $OLLAMA_MODELS ] && die "Couldn't find OLLAMA_MODELS ($OLLAMA_MODELS)" [ ! -d "$OLLAMA_MODELS/blobs" -o ! -d "$OLLAMA_MODELS/manifests" ] && die "blobs or manifests directory not found" manifest="manifests/$registry/$library/$name/$tag" [ ! -f "$OLLAMA_MODELS/$manifest" ] && die "Model $model not found at $manifest" blobs=$(jq -r '[.config.digest, (.layers[].digest)]|.[]' "$OLLAMA_MODELS/$manifest" | sed -e 's@^sha256:@blobs/sha256-@') dst="$(realpath ./${model//\//-})".zip (cd "$OLLAMA_MODELS" && $DRYRUN zip -$store $dst $manifest $blobs) } for model in $* ; do zip_model $model done ```
Author
Owner

@JoeLoginIsAlreadyTaken commented on GitHub (Apr 13, 2026):

Thank you very much. Very cool script.

<!-- gh-comment-id:4239124090 --> @JoeLoginIsAlreadyTaken commented on GitHub (Apr 13, 2026): Thank you very much. Very cool script.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/ollama#87588