13 min read

LM Studio CLI: full automation — downloading, configuring and running Qwen models without GUI

LM Studio CLI: full automation — downloading, configuring and running Qwen models without GUI

Part of Running LLMs on Your Own Hardware: From “Will It Even Fit” to a Model That Does Your Work — running large language models on your own hardware.

📌 BONUS ARTICLE — Series supplement: the CLI layer underpinning all benchmarks. Scripts: 04_lms_cli_qwen.py

LM Studio CLI on Windows 11 is a feature many LM Studio users never touch. Yet for anyone running benchmarks, testing several models in a row, or wiring local LLMs into their own scripts, the CLI is the foundation. This article covers every key lms command, the parameters that matter, and how to automate model management without opening the GUI once. Every command output below is captured from a real session, and the CLI step timings and inference throughput are measured — Qwen3.5-2B Q4_K_M, n=10 runs per step, mean ± std, no estimates.

Key takeaways
  • lms replaces the GUI for downloading, loading, and serving models.
  • The full loop — list, load, serve, unload — is scriptable in a few lines.
  • New model architectures may need a one-line runtime update before they load.
  • After lms load, the OpenAI-compatible server is live on port 1234.
  • Real measurement (n=10): lms load on Qwen3.5-2B averages 7.0s ± 0.5s; the model itself generates 20.7–28.5 tok/s depending on prompt type.

Why the CLI beats the GUI for real work

The GUI is fine for a first chat. It falls apart the moment you repeat yourself. Testing five models means five rounds of clicking through download, load, and unload dialogs, and no record of what you did. The CLI turns that into a script you can rerun, share, and version.

Three benefits stand out. First, reproducibility: a script sets the same context length and GPU offload every time, so results are comparable. Second, automation: you can queue an overnight sweep across many models and wake up to a results file. Third, integration: the CLI slots into CI, into Python, and into a headless server where no desktop exists. For benchmarking, those three properties are not nice-to-haves — they are the whole point.

What lms is and where to find it

LM Studio ships a CLI tool called lms. The installer places it under your user profile and wires it onto PATH, so on a standard Windows 11 install you can call it from any terminal. The binary lives here:

%USERPROFILE%.cachelm-studiobinlms.exe

Verify it, then note one important quirk: the CLI needs the LM Studio background service running. If a command hangs on “Waking up LM Studio service”, launch the LM Studio app once to start the service, then retry.

lms version
lms server start          # -> Success! Server is now running on port 1234

lms command map — cheat sheet

LM Studio CLI benchmark session step timing chart for Qwen3.5-2B, n=10 runs per step, real measured data with error bars
Diagram 1: Real step timing for a benchmark session — Qwen3.5-2B Q4_K_M, n=10 runs per step (mean ± std). Download and rm are excluded because they are network- and disk-bound, not CLI-bound. Measured with a dedicated benchmark script on this machine.
CommandWhat it does
lms --versionCLI version
lms lsList local models
lms ls --jsonList in JSON format (for scripts)
lms server startStart API server (port 1234)
lms server stopStop server
lms server statusServer status
lms get ORG/REPO@QUANTDownload model from HuggingFace
lms load ORG/REPO@QUANTLoad model into server
lms unloadUnload active model
lms unload --allUnload all models
lms rm ORG/REPODelete model from disk
lms psRunning models
lms log streamLive server logs

The most-used command is lms ls. It groups models by type and marks which one is loaded. Here is a real listing from a working machine:

$ lms ls
You have 3 models, taking up 30.41 GB of disk space.

LLM                                  PARAMS   ARCH        SIZE       DEVICE
google/gemma-4-12b-qat (1 variant)   12B      gemma4      7.15 GB    Local   ✓ LOADED
qwen3.6-35b-a3b-mtp                   35B-A3B  qwen35moe   23.17 GB   Local

EMBEDDING                              PARAMS   ARCH         SIZE
text-embedding-nomic-embed-text-v1.5            Nomic BERT   84.11 MB

Notice how the output separates LLMs from embedding models and shows the exact architecture. That detail matters, because the architecture decides whether your current runtime can load the model at all — as the next section shows.

A more recent real session, after downloading the small model used for the benchmarks in this article:

$ lms ls
You have 2 models, taking up 2.03 GB of disk space.

LLM           PARAMS    ARCH      SIZE       DEVICE
qwen3.5-2b    2B        qwen35    1.94 GB    Local

EMBEDDING                               PARAMS    ARCH          SIZE        DEVICE
text-embedding-nomic-embed-text-v1.5              Nomic BERT    84.11 MB    Local

Downloading Qwen models via CLI

Any GGUF model from HuggingFace is downloaded via lms get. The full ID consists of organisation, repository name, and quantization after a colon:

# Qwen3.6-35B-A3B in Q4_K_M quantization (~32 GB)
lms get lmstudio-community/Qwen3.6-35B-A3B-GGUF@Q4_K_M

# Qwen3-0.6B — lightweight model for drafter/agent
lms get lmstudio-community/Qwen3-0.6B-GGUF@Q4_K_M

# Qwen3-VL 7B — vision model
lms get lmstudio-community/Qwen3-VL-7B-Instruct-GGUF@Q4_K_M

Always check free disk space before downloading. LM Studio does not do this automatically:

Free ebook

Free AI Video, Generated Locally

Working scripts and measured benchmarks. Free.

No spam. Unsubscribe at any time.

# PowerShell — free GB on drive C:
[math]::Round((Get-PSDrive C).Free / 1GB, 1)

Loading with parameters — complete option list

The lms load command accepts several important parameters:

lms load lmstudio-community/Qwen3.6-35B-A3B-GGUF@Q4_K_M `
  --context-length 8192 `
  --gpu max

What the parameters mean:

  • --context-length 8192 — context window size in tokens. Larger = more VRAM (KV-cache). Qwen3.6 natively supports up to 262K tokens, but with Q4_K_M on 48 GB VRAM safely up to 32K.
  • --gpu max — offload all layers to GPU. You can also pass an integer (e.g. 40) = how many layers to GPU, rest to CPU.
Gotcha confirmed live while benchmarking this article: the org/repo@quant identifier works for lms get, but once a model is downloaded, lms load may reject that same identifier with Cannot find a model matching the provided model key and drop into an interactive picker — which hangs any non-interactive script. Use the short key from lms ls or lms ps instead (e.g. lms load qwen3.5-2b, not lms load lmstudio-community/Qwen3.5-2B-GGUF@Q4_K_M). Always test the exact load command interactively once before wiring it into an unattended script.
Note on MTP in LM Studio: In LM Studio 0.4.14, Multi-Token Prediction is not a flag on lms load. MTP requires loading a separate GGUF model variant (e.g. qwen3.6-35b-a3b-mtp). On AMD gfx1100 (RDNA3), this MTP variant currently fails to load with Error: Failed to load model in LM Studio.
✓ MTP works with llama-server (Vulkan): The same MTP-GGUF model (Qwen3.6-35B-A3B-UD-Q4_K_S) loads and runs correctly via llama-server with --spec-type draft-mtp --spec-draft-n-max 4 on AMD gfx1100 (RDNA3, Vulkan). Real benchmark on AMD PRO W7900: baseline 49.7 tok/s → MTP 91.8 tok/s (1.85× speedup). See Multi-Token Prediction on AMD W7900 for the full methodology and results.

Updating the runtime for new model architectures

Here is a real gotcha the CLI makes easy to fix. A brand-new architecture can refuse to load on an older engine, and the error is unhelpfully terse:

$ lms load google/gemma-4-12b-qat --gpu max
Error: Failed to load model.
   (X) CAUSE  Failed to load model

The cause is not memory and not the model file. LM Studio runs on a bundled llama.cpp engine, and a fresh architecture like gemma4 needs a newer engine build than the one installed. The lms runtime commands manage exactly this. First check what is available:

lms runtime ls          # list installed engines
lms runtime update --yes # pull the newest compatible engine

On the test machine, the update bumped the Vulkan engine from 2.11.0 to 2.24.0. After that, the same load command succeeded in seconds:

$ lms load google/gemma-4-12b-qat --gpu max --context-length 8192
Model loaded successfully in 22.11s.

So when a new model will not load, do not assume the file is broken. Update the runtime first. This single step saves a lot of guesswork, and it is invisible in the GUI unless you know to look for it.

Multi-model test sequence — automation

Model disk usage chart with real GB sizes for embedding, 2B, 12B and 35B-A3B models, measured via lms ls
Diagram 2: Real disk usage per model, read straight from lms ls — the 2B model tested in this article next to the 12B and 35B-A3B models from earlier in this series (already deleted from this machine to free space, per the workflow below). lms rm is what recovers that space before the next download.

Testing several models in a row without a GUI is a sequence: download → load → test → unload → (optionally) delete. In PowerShell:

$models = @(
    "lmstudio-community/Qwen3.6-35B-A3B-GGUF@Q4_K_M",
    "lmstudio-community/Mistral-Small-3.1-24B-Instruct-2503-GGUF@Q4_K_M",
    "lmstudio-community/gemma-3-27b-it-GGUF@Q4_K_M"
)

foreach ($model in $models) {
    Write-Host "=== Testing: $model ===" -ForegroundColor Cyan
    lms get $model
    lms load $model --context-length 8192 --gpu max
    python run_my_benchmark.py
    lms unload --all
    $freeGB = [math]::Round((Get-PSDrive C).Free / 1GB, 1)
    Write-Host "Free disk space: $freeGB GB"
    if ($freeGB -lt 15) {
        Write-Host "Low disk space — removing model" -ForegroundColor Yellow
        lms rm ($model.Split("@")[0])
    }
}

Python does the same more elegantly — the LMSManager class from the repository handles all these steps automatically, including asking for confirmation before deleting a model.

Verification via REST API after loading

After lms load the server is available on port 1234. Verification in PowerShell:

# List loaded models
Invoke-RestMethod http://localhost:1234/v1/models | ConvertTo-Json

# Quick inference test
$body = @{
    model = "local-model"
    messages = @(@{role="user"; content="Reply in one sentence."})
    max_tokens = 50
} | ConvertTo-Json

Invoke-RestMethod -Uri http://localhost:1234/v1/chat/completions `
    -Method POST -ContentType "application/json" -Body $body

To see what is loaded and how much context it holds, use lms ps. The real output confirms the model, its context window, and its idle state:

$ lms ps
IDENTIFIER               MODEL                    STATUS   SIZE      CONTEXT   DEVICE
google/gemma-4-12b-qat   google/gemma-4-12b-qat   IDLE     7.15 GB   8192      Local

Real benchmark: how fast is the CLI itself?

Every number below comes from a dedicated benchmark script that drives lms the same way a scripted overnight sweep would: unload, load, check status, run inference, unload again — 10 times per step, model Qwen3.5-2B Q4_K_M, context 4096, full GPU offload. Diagram 1 (above) plots the same data.

StepMeanStd devn
lms server status0.93 s± 0.06 s10
lms ls1.08 s± 0.19 s10
lms load qwen3.5-2b (ctx 4096, GPU max)7.03 s± 0.48 s10
lms ps1.13 s± 0.05 s10
lms unload --all1.19 s± 0.12 s10

Download and lms rm are intentionally excluded from this table — they depend on network speed and NVMe write speed, not on the CLI, so averaging them here would misrepresent what the tool itself costs. The one number worth remembering: a cold lms load on a small model is a ~7-second tax per cycle, which matters if your sweep script loads and unloads dozens of times overnight.

Inference throughput, same model, streamed via the OpenAI-compatible endpoint, n=10 per prompt category:

Prompt categoryThroughputTTFT
Short code (≤300 tok)20.7 ± 0.4 tok/s2396 ± 58 ms
Medium reasoning (≤500 tok)28.5 ± 0.2 tok/s2422 ± 39 ms
Long generation (≤800 tok)26.9 ± 1.0 tok/s2341 ± 64 ms

TTFT sits around 2.3–2.4 seconds regardless of prompt size — on this machine that is mostly prompt-processing overhead for the small system+user prompt, not something that scales with the requested output length. Throughput is lower for the shortest prompt, which is expected: with fewer tokens to generate, a larger share of the request time is spent on the fixed per-request overhead rather than steady-state decoding.

Log monitoring during model loading

While loading a large model (e.g. 32 GB) it is worth watching the logs to detect OOM errors or HIP backend issues:

# In a separate terminal — live logs
lms log stream

# Filter for errors only
lms log stream | Select-String -Pattern "error|warning|failed"

Common errors and fixes

ErrorCauseSolution
lms: not recognizedlms not in PATHAdd %LOCALAPPDATA%ProgramsLM-Studio to PATH
out of memory on loadInsufficient VRAM or RAMReduce context length or use a lower quantization
model not foundWrong model IDCheck lms ls — exact name from the local list
MTP not workingModel has no MTP head in GGUFUse Qwen3 or DeepSeek-V3 models; fallback: 01b_mtp_rocm.py
Server won’t startPort 1234 in usenetstat -ano | findstr :1234 → kill PID

Full session — from zero to benchmark

# 1. Start server
lms server start

# 2. Check what you have locally
lms ls

# 3. Download Qwen3.6 if missing
lms get lmstudio-community/Qwen3.6-35B-A3B-GGUF@Q4_K_M

# 4. Load with full GPU offload
lms load lmstudio-community/Qwen3.6-35B-A3B-GGUF@Q4_K_M `
  --context-length 8192 --gpu max

# 5. Run benchmark
python 01_mtp_benchmark.py --no-download

# 6. Unload
lms unload --all

# 7. Check results
python 02_analyze_results.py

Scripting the CLI from Python

The CLI shines inside automation. Because every command is deterministic and returns clean text, you can drive it from Python with subprocess and parse the results. The pattern below loads a model, runs a benchmark, and unloads it, so an overnight job can sweep a whole model list unattended.

import subprocess

def run(cmd: str) -> str:
    return subprocess.run(cmd, shell=True, capture_output=True, text=True).stdout

run("lms load google/gemma-4-12b-qat --gpu max --context-length 8192")
# ... hit http://localhost:1234/v1/chat/completions and record metrics ...
run("lms unload --all")

This is how the benchmark scripts in this series stay reproducible. They never depend on a human clicking through the GUI, so the same run produces the same setup every time. For a shared workstation, that repeatability is the difference between a trustworthy benchmark and a one-off anecdote.

Frequently asked questions

Where is the lms binary on Windows?

It installs under %USERPROFILE%.cachelm-studiobinlms.exe and is added to PATH by the installer. If lms is not recognised, reopen your terminal or add that folder to PATH manually.

Why does an lms command hang on “Waking up LM Studio service”?

The CLI needs the LM Studio background service. Launch the LM Studio app once so the service starts, then rerun the command. This is the most common first-time snag.

A new model fails to load — is the file corrupt?

Usually not. A new architecture often needs a newer engine. Run lms runtime update --yes, then load again. Only after the runtime is current should you suspect the file.

Can I run lms with no GUI at all?

Yes, once the service is running. The full loop — get, load, ps, unload — works headless, which is exactly what you want on a remote or shared box.

How do I free VRAM after a batch job?

Call lms unload --all. Loading a model reserves VRAM until you unload it, so releasing it between jobs keeps the GPU available for the next task.

Summary

LM Studio CLI is the tool that transforms your workflow from “clicking through the GUI” to “run a script and grab a coffee”. For benchmarking multiple models, testing MTP configurations, and integrating with your own Python pipelines — the CLI is essential. The demo script 04_lms_cli_qwen.py walks through every step and prints each command with its output — ready to screenshot for your own documentation. On this machine, with Qwen3.5-2B Q4_K_M, a full unload→load→inference→unload cycle costs about 9–10 seconds of pure CLI overhead on top of whatever the model itself generates — small enough to not think about, and reproducible enough to trust in an unattended sweep.

Companion code — every script and benchmark from this series lives in one repository: github.com/bestin-it/qwen-local-ai-scripts.

Free ebook

Free AI Video, Generated Locally

Run Wan 2.1 in ComfyUI on your own GPU — the scripts I use, measured times, sample clips. No cloud, no API keys.

No spam. Unsubscribe at any time.

Artur Poniedziałek
Artur Poniedziałek
IT Expert & Project Manager
🤖 AI ⚡ PM 🐍 Python 🖥️ Local AI

IT Expert & Project Manager with 15+ years of experience. Exploring practical AI applications — from local LLMs and RAG systems to workflow automation. Writing to share knowledge and inspire others to experiment with new technologies.

Leave a Reply

Your email address will not be published. Required fields are marked *