How to Move Local AI Models to a New Machine

Copy Ollama, Hugging Face and LM Studio model stores to a new computer, keep custom Modelfiles working, and check the weights arrived intact.

You have a local AI setup that works: models on disk, a couple of custom ones you tuned, and the habit of keeping inference on your own hardware. Then the laptop changes, or the server gets rebuilt, and the setup has to move with you.

Re-downloading is the default outcome, and on a store of tens of gigabytes it is an evening you did not need to spend. Copying the folder is the other default, and that is where the breakage starts, because most of what makes a local setup work is not in the weights. It is in absolute paths, environment variables, tokens and saved Modelfiles, and none of those travel inside a file copy on their own.

This is the order to move in, and the checks that tell you the new machine really is the old setup.

TL;DR

  • Ollama keeps every model in one directory: ~/.ollama/models on macOS, /usr/share/ollama/.ollama/models on Linux, C:\Users\%username%\.ollama\models on Windows. Copy that directory, and point OLLAMA_MODELS at it if it lands somewhere else (Ollama FAQ).
  • A saved Modelfile records the absolute path of the blob it was built from. ollama show --modelfile prints that path next to the instruction to replace the FROM line with the model name and tag (Modelfile reference).
  • Ollama’s environment variables are set by a different mechanism on each operating system, so the settings behind the old install have to be written again by hand (FAQ).
  • Hugging Face keeps models in a cache under HF_HOME, which defaults to ~/.cache/huggingface, and stores the access token in the same tree (environment variables).
  • hf cache verify checks local files against the checksums on the Hub, which is the command that tells you the copy arrived intact (CLI guide).
  • A cache copied between operating systems can break on symlinks. The Hugging Face documentation says “Symlinks created on Linux are not always traversable on Windows, leading to errors”, and HF_HUB_DISABLE_SYMLINKS=1 avoids the problem “at the cost of disk-space deduplication” (environment variables).
  • LM Studio expects a fixed shape, ~/.lmstudio/models/publisher/model/model-file.gguf, and lms import moves a GGUF you already have into it (LM Studio).

What actually has to move

Three things travel, and the order matters more than the method.

  1. The weights. Large, portable, and checkable against a checksum, which makes them the easy half.
  2. The settings. Small, portable and path-sensitive: Ollama environment variables, the Ollama key, the Hugging Face token, and the Modelfiles behind any custom model. These are the ones that break.
  3. The check. A way to confirm the new machine sees the same models and the same files, rather than a fresh empty install that happens to share a name.

Each runtime covered here keeps its models in directories, so copying the directory and repairing the paths is the whole job.

Ollama: copy the store, then repair the paths

Inventory before you copy. ollama ls lists the models on the machine and ollama rm removes one, so that listing is the manifest of what has to come with you (CLI reference).

Copy the store. The Ollama FAQ gives one directory per operating system:

OSDefault model directory
macOS~/.ollama/models
Linux/usr/share/ollama/.ollama/models
WindowsC:\Users\%username%\.ollama\models

To keep it somewhere else, set the environment variable OLLAMA_MODELS to the chosen directory. On Linux with the standard installer, the FAQ is explicit that the ollama user needs read and write access to that directory, assigned with sudo chown -R ollama:ollama <directory>. Skip that and the service has no read access to the models it is meant to load.

Repair the FROM lines. This is the step that is easy to miss. ollama show --modelfile llama3.2 prints the model’s Modelfile, and a comment near the top of the printed file says what to do about it: “To build a new Modelfile based on this one, replace the FROM line with:”, followed by FROM llama3.2:latest on the next line. The FROM line itself points into the store it was generated on, something like /Users/pdevine/.ollama/models/blobs/sha256-00e1317cbf74d901080d7100f57580ba8dd8de57203072dc6f668324ba545f29. Copy the store to a different machine and that path does not exist there, even though the model does. The fix is to rebuild the custom model from the name and tag rather than the blob path, with ollama create -f Modelfile (Modelfile reference, CLI reference).

Bring your own Modelfile files across as well. They are the readable source of a custom model, and the parameters inside them are the part you tuned. If a model was built from a GGUF file you downloaded separately, the import documentation shows the same principle from the other direction: a Modelfile with FROM /path/to/file.gguf and an ollama create command to build it (importing a model).

Write the environment variables again. The values do not travel in a file copy, and the mechanism differs per operating system. On macOS, the FAQ documents launchctl setenv for each variable, then restarting the app. On Linux, systemctl edit ollama.service and an Environment= line under [Service], followed by systemctl daemon-reload and systemctl restart ollama. On Windows, quit the app first, then edit the user environment variables and start it again from the Start menu. Whatever was set on the old machine, OLLAMA_HOST if you exposed the server, OLLAMA_NUM_PARALLEL if you raised it above its default of 1, OLLAMA_KEEP_ALIVE if you wanted weights to stay resident, OLLAMA_NO_CLOUD if you wanted the install to stay local, has to be written on the new machine in its own way.

Bring the key if you use one. Ollama’s public key sits at ~/.ollama/id_ed25519.pub on macOS, /usr/share/ollama/.ollama/id_ed25519.pub on Linux and C:\Users\<username>\.ollama\id_ed25519.pub on Windows. You need it to push a model to ollama.com, to pull a private model, or to use Ollama’s cloud models.

If Ollama runs in Docker. The store is the volume, not a folder in your home directory. Ollama’s Docker documentation runs the container with -v ollama:/root/.ollama, so the thing to copy is the volume itself (Docker documentation).

Hugging Face: move the cache, not the download

The cache lives under HF_HOME, which the Hugging Face documentation describes as the place “where huggingface_hub will locally store data. In particular, your token and the cache will be stored in this folder”, defaulting to ~/.cache/huggingface unless XDG_CACHE_HOME is set. The model cache itself is HF_HUB_CACHE, which defaults to $HF_HOME/hub.

Inventory. hf cache ls lists the cached repositories, and the CLI guide shows it reporting “Found 3 repo(s) for a total of 5 revision(s) and 35.5G on disk”. The same command takes --format json for scripts, --filter "size>30g" to find the heavyweights, and --cache-dir to point at an alternative location.

Copy and repoint. Copy the HF_HOME tree, then set HF_HOME, or HF_HUB_CACHE if you keep them apart, on the new machine.

Check the symlinks. The cache links blobs into snapshot directories, and the documentation names the failure mode: “Symlinks created on Linux are not always traversable on Windows, leading to errors. Setting HF_HUB_DISABLE_SYMLINKS=1 avoids this problem at the cost of disk-space deduplication.” When the copy crosses operating systems or lands on a network share, set that variable before the first run. The same page documents HF_HUB_DISABLE_SHARED_BLOBS for turning off the cache-wide shared blob store, where “identical files are stored on disk only once across repos and can be reused without re-fetching”.

Verify the copy. hf cache verify answers the real question. The CLI guide describes it as validating “local files against their checksums on the Hub”, and it accepts either a cache snapshot or a plain directory through --local-dir. Run it over the repositories you moved before trusting the new machine.

Two useful variants. hf download <repo> --local-dir <dir> writes a portable directory instead of a cache, with a .cache/huggingface/ metadata folder at its root. And hf cache prune reclaims “every detached (unreferenced) revision”, “any leftover .incomplete files from interrupted downloads”, and “shared blobs no longer referenced by any cached repo”, which trims the cache before it is copied.

Prove the install is self-sufficient. HF_HUB_OFFLINE=1 stops the library making HTTP calls to the Hub: “If you try to download files, only the cached files will be accessed.” Run the moved model with it set and the copy is doing the work.

LM Studio: the folder shape is the setup

LM Studio’s documentation is explicit that a model you already have can be used “by placing them in the expected directory structure”, and that the expected structure is ~/.lmstudio/models/publisher/model/model-file.gguf, because “LM Studio aims to preserves the directory structure of models downloaded from Hugging Face”. Copy that tree and the models come with it. For a single file, lms import <path/to/model.gguf> does the same job, and its flags pick the mechanism: --copy to “Copy the file instead of moving it”, --hard-link or --symbolic-link to avoid duplicating a large file on disk, and --dry-run to “Do not perform the import, just show what would be done” (import documentation, lms import reference). LM Studio also keeps the models directory adjustable from My Models in the app (downloading a model).

llama.cpp: a model is a file

Running a server directly leaves less to move. The llama.cpp server takes -m, --model FNAME, which its README describes as the “model path to load” with the environment variable LLAMA_ARG_MODEL, so a GGUF file copied across is all that is needed. The llama.cpp router, which serves several models from one endpoint, looks in three places: the cache, controlled by the LLAMA_CACHE environment variable, a custom directory set with --models-dir, and a preset file set with --models-preset. It can also pull from the Hub with -hf, and takes its token with -hft, whose documented default is the value of the HF_TOKEN environment variable. Setting HF_TOKEN in the environment therefore covers the Python stack and llama.cpp together (server README, environment variables).

What usually breaks

  • The FROM line in a saved Modelfile, pointing at a blob path on the machine you left.
  • The ollama service user’s ownership of the model directory on Linux.
  • Environment variables, which are set by a different mechanism on each operating system and are never copied with a folder.
  • The Hugging Face token, when it lived in $HF_HOME/token rather than in the environment.
  • Symlinks in a copied Hugging Face cache, when the copy crosses operating systems.
  • The Ollama key, when you push models to ollama.com or pull private ones.
  • The volume behind a container install, which is not in your home directory.

The bottom line

Move in three passes. First the weights, with a copy you can check: ollama ls before and after for Ollama, hf cache verify for Hugging Face, the same folder tree for LM Studio. Second the credentials, which are small and easy to lose: the Ollama key, the Hugging Face token. Third the settings, written again by hand in the new operating system’s own way, with the environment variables and the Modelfiles that carry your custom models.

The order matters, because the checks only mean something once the files are in place, and the settings only stick once the files are found.