Instructions to use unsloth/GLM-4.5-Air-GGUF with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use unsloth/GLM-4.5-Air-GGUF with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="unsloth/GLM-4.5-Air-GGUF") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("unsloth/GLM-4.5-Air-GGUF", dtype="auto") - llama-cpp-python
How to use unsloth/GLM-4.5-Air-GGUF with llama-cpp-python:
# !pip install llama-cpp-python from llama_cpp import Llama llm = Llama.from_pretrained( repo_id="unsloth/GLM-4.5-Air-GGUF", filename="BF16/GLM-4.5-Air-BF16-00001-of-00005.gguf", )
llm.create_chat_completion( messages = [ { "role": "user", "content": "What is the capital of France?" } ] ) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use unsloth/GLM-4.5-Air-GGUF with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible server with a web UI: llama serve -hf unsloth/GLM-4.5-Air-GGUF:UD-Q4_K_XL # Run inference directly in the terminal: llama cli -hf unsloth/GLM-4.5-Air-GGUF:UD-Q4_K_XL
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf unsloth/GLM-4.5-Air-GGUF:UD-Q4_K_XL # Run inference directly in the terminal: llama cli -hf unsloth/GLM-4.5-Air-GGUF:UD-Q4_K_XL
Use pre-built binary
# Download pre-built binary from: # https://github.com/ggerganov/llama.cpp/releases # Start a local OpenAI-compatible server with a web UI: ./llama-server -hf unsloth/GLM-4.5-Air-GGUF:UD-Q4_K_XL # Run inference directly in the terminal: ./llama-cli -hf unsloth/GLM-4.5-Air-GGUF:UD-Q4_K_XL
Build from source code
git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-server llama-cli # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama-server -hf unsloth/GLM-4.5-Air-GGUF:UD-Q4_K_XL # Run inference directly in the terminal: ./build/bin/llama-cli -hf unsloth/GLM-4.5-Air-GGUF:UD-Q4_K_XL
Use Docker
docker model run hf.co/unsloth/GLM-4.5-Air-GGUF:UD-Q4_K_XL
- LM Studio
- Jan
- vLLM
How to use unsloth/GLM-4.5-Air-GGUF with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "unsloth/GLM-4.5-Air-GGUF" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "unsloth/GLM-4.5-Air-GGUF", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/unsloth/GLM-4.5-Air-GGUF:UD-Q4_K_XL
- SGLang
How to use unsloth/GLM-4.5-Air-GGUF with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "unsloth/GLM-4.5-Air-GGUF" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "unsloth/GLM-4.5-Air-GGUF", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "unsloth/GLM-4.5-Air-GGUF" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "unsloth/GLM-4.5-Air-GGUF", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Ollama
How to use unsloth/GLM-4.5-Air-GGUF with Ollama:
ollama run hf.co/unsloth/GLM-4.5-Air-GGUF:UD-Q4_K_XL
- Unsloth Studio
How to use unsloth/GLM-4.5-Air-GGUF with Unsloth Studio:
Install Unsloth Studio (macOS, Linux, WSL)
curl -fsSL https://unsloth.ai/install.sh | sh # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for unsloth/GLM-4.5-Air-GGUF to start chatting
Install Unsloth Studio (Windows)
irm https://unsloth.ai/install.ps1 | iex # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for unsloth/GLM-4.5-Air-GGUF to start chatting
Using HuggingFace Spaces for Unsloth
# No setup required # Open https://huggingface.co/spaces/unsloth/studio in your browser # Search for unsloth/GLM-4.5-Air-GGUF to start chatting
- Pi
How to use unsloth/GLM-4.5-Air-GGUF with Pi:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf unsloth/GLM-4.5-Air-GGUF:UD-Q4_K_XL
Configure the model in Pi
# Install Pi: npm install -g @mariozechner/pi-coding-agent # Add to ~/.pi/agent/models.json: { "providers": { "llama-cpp": { "baseUrl": "http://localhost:8080/v1", "api": "openai-completions", "apiKey": "none", "models": [ { "id": "unsloth/GLM-4.5-Air-GGUF:UD-Q4_K_XL" } ] } } }Run Pi
# Start Pi in your project directory: pi
- Hermes Agent new
How to use unsloth/GLM-4.5-Air-GGUF with Hermes Agent:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf unsloth/GLM-4.5-Air-GGUF:UD-Q4_K_XL
Configure Hermes
# Install Hermes: curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash hermes setup # Point Hermes at the local server: hermes config set model.provider custom hermes config set model.base_url http://127.0.0.1:8080/v1 hermes config set model.default unsloth/GLM-4.5-Air-GGUF:UD-Q4_K_XL
Run Hermes
hermes
- Atomic Chat new
- Docker Model Runner
How to use unsloth/GLM-4.5-Air-GGUF with Docker Model Runner:
docker model run hf.co/unsloth/GLM-4.5-Air-GGUF:UD-Q4_K_XL
- Lemonade
How to use unsloth/GLM-4.5-Air-GGUF with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull unsloth/GLM-4.5-Air-GGUF:UD-Q4_K_XL
Run and chat with the model
lemonade run user.GLM-4.5-Air-GGUF-UD-Q4_K_XL
List all available models
lemonade list
Tool Calls Not Working with –jinja Option
First, thank you very much for always distributing high-performance GGUF models.
I downloaded the Q4_K_XL model, but tool calls are not working properly in Claude Code.
I loaded the model with the –jinja option, but when I enter a command in Claude Code, only text appears like this and no actual call is executed:
“
⏺ I’ll help you clean up unused CSS in the TeacherEntry.vue file. Let me first read the file to analyze the template and styles.
Read
file_path
/Users/sampro/math-geogebra/math-geogebra-front/src/components/Entry/TeacherEntry.vue
“
Just in case, I tried using the original model’s template with –jinja –chat-template-file official_glm45_template.jinja, but got the following:
“
common_init_from_params: setting dry_penalty_last_n to ctx_size = 131072
common_init_from_params: warming up the model with an empty run - please wait … (–no-warmup to disable)
common_chat_templates_init: failed to parse chat template (defaulting to chatml): Expected comma in tuple at row 47, column 102:
{{ visible_text(m.content) }}
{{- ‘/nothink’ if (enable_thinking is defined and not enable_thinking and not visible_text(m.content).endswith(”/nothink”)) else ‘’ -}}
{%- elif m.role == ‘assistant’ -%}
srv init: initializing slots, n_slots = 1
slot init: id 0 | task -1 | new slot n_ctx_slot = 131072
main: model loaded
“
After this, it looked like the model was being called from Claude Code, but it ended up stuck in endless tool invocation and I had to forcibly terminate it.
Does this mean there is a problem with the template? I’d appreciate any help.
Thank you as always.
Edit : I used the version built from the source this morning.
I have the same problem but with qwen code. Does it use XML template like qwen3-coder? I am not sure.
Hi, I have the same or a similar problem:
- llama-b6089-bin-win-cuda-12.4-x64
- GLM-4.5-Air-IQ4_NL-00001-of-00002.gguf downloaded at 2025-08-05T09:32:00Z (UTC)
- .\llama-server.exe -ngl 99 -c 60000 -fa -ctk q8_0 -ctv q8_0 -m "[...]\GLM-4.5-Air-GGUF\GLM-4.5-Air-IQ4_NL-00001-of-00002.gguf" --jinja -ub 512 --temp 0.6 --top-p 0.95 --top-k 20 --repeat-penalty 1.05 --n-cpu-moe 44 --no-mmap -sm none
- tested with Cline and RooCode
I get the following error from llama.cpp as soon as a tool call result gets posted to the model:
srv log_server_r: request: POST /v1/chat/completions 127.0.0.1 200
got exception: {"code":500,"message":"Value is not callable: null at row 56, column 70:\n {%- if '' in content %}\n {%- set reasoning_content = ((content.split('')|first).rstrip('\n').split('')|last).lstrip('\n') %}\n ^\n {%- set content = (content.split('')|last).lstrip('\n') %}\n at row 56, column 72:\n {%- if '' in content %}\n {%- set reasoning_content = ((content.split('')|first).rstrip('\n').split('')|last).lstrip('\n') %}\n ^\n {%- set content = (content.split('')|last).lstrip('\n') %}\n at row 56, column 85:\n {%- if '' in content %}\n {%- set reasoning_content = ((content.split('')|first).rstrip('\n').split('')|last).lstrip('\n') %}\n ^\n {%- set content = (content.split('')|last).lstrip('\n') %}\n at row 56, column 106:\n {%- if '' in content %}\n {%- set reasoning_content = ((content.split('')|first).rstrip('\n').split('')|last).lstrip('\n') %}\n ^\n {%- set content = (content.split('')|last).lstrip('\n') %}\n at row 56, column 108:\n {%- if '' in content %}\n {%- set reasoning_content = ((content.split('')|first).rstrip('\n').split('')|last).lstrip('\n') %}\n ^\n {%- set content = (content.split('')|last).lstrip('\n') %}\n at row 56, column 9:\n {%- if '' in content %}\n {%- set reasoning_content = ((content.split('')|first).rstrip('\n').split('')|last).lstrip('\n') %}\n ^\n {%- set content = (content.split('')|last).lstrip('\n') %}\n at row 55, column 36:\n{%- else %}\n {%- if '' in content %}\n ^\n {%- set reasoning_content = ((content.split('')|first).rstrip('\n').split('')|last).lstrip('\n') %}\n at row 55, column 5:\n{%- else %}\n {%- if '' in content %}\n ^\n {%- set reasoning_content = ((content.split('')|first).rstrip('\n').split('')|last).lstrip('\n') %}\n at row 54, column 12:\n {%- set reasoning_content = m.reasoning_content %}\n{%- else %}\n ^\n {%- if '' in content %}\n at row 52, column 1:\n{%- set content = visible_text(m.content) %}\n{%- if m.reasoning_content is string %}\n^\n {%- set reasoning_content = m.reasoning_content %}\n at row 48, column 35:\n{{- '/nothink' if (enable_thinking is defined and not enable_thinking and not content.endswith("/nothink")) else '' -}}\n{%- elif m.role == 'assistant' -%}\n ^\n<|assistant|>\n at row 45, column 1:\n{% for m in messages %}\n{%- if m.role == 'user' -%}<|user|>\n^\n{% set content = visible_text(m.content) %}{{ content }}\n at row 44, column 24:\n{%- endfor %}\n{% for m in messages %}\n ^\n{%- if m.role == 'user' -%}<|user|>\n at row 44, column 1:\n{%- endfor %}\n{% for m in messages %}\n^\n{%- if m.role == 'user' -%}<|user|>\n at row 1, column 1:\n[gMASK]\n^\n{%- if tools -%}\n","type":"server_error"}
But just omitting the parameter --jinja seems to work for me..
Looks like built in "fixed" jinja template is just broken 😔
https://github.com/ggml-org/llama.cpp/pull/15086
Is this possibly related to the issue?
Edit : I tried applying it, but with the --jinja option, it still only outputs the text for the tool call, and the tool doesn’t actually get invoked.
I can confirm tool calls are not working for GLM-4.5-Air-UD-Q2_K_XL.gguf file hash SHA256: a54d4870a1b4f5bc6aed46ae36984a0bd0783fad6bff67ff8369309f19927fa0
I do not see an error in llama.cpp though, using build: 6091 (22f060c9)
I can confirm tool calls are not working for
GLM-4.5-Air-UD-Q2_K_XL.gguffile hashSHA256: a54d4870a1b4f5bc6aed46ae36984a0bd0783fad6bff67ff8369309f19927fa0I do not see an error in llama.cpp though, using build: 6091 (22f060c9)
Which agent tool(cline, roo, claude code, ..etc) did you test it on?
Which agent tool(cline, roo, claude code, ..etc) did you test it on?
Self programmed agent. I am using llama.cpp with --jinja and let it do the tool call parsing etc. using the OpenAI compatible API chat endpoint of llama.cpp
I'm also seeing tool calling not work.
The chat template from the model creator instructs the model to format its tool calls in XML: https://huggingface.co/zai-org/GLM-4.5-Air/blob/main/chat_template.jinja.
These GGUFs faithfully reproduce that language, so that's what the model is doing. Here's an example of what the IQ4_XS quant outputted for a tool call:
<tool_call>tool_brave_web_search_post
<arg_key>query</arg_key>
<arg_value>test search</arg_value>
<arg_key>count</arg_key>
<arg_value>5</arg_value>
</tool_call>
But then the app (I'm using open-webui) doesn't parse it and treat it as a tool call (I think it only handles json-formatted tool calls).
Maybe apps need to be modified to handle xml-formatted tool calls.
GLM 4.5 anthropic style tool calling jinja template - https://pastebin.com/CfMw7hFS
But,
common_chat_templates_init: failed to parse chat template (defaulting to chatml): Expected comma in tuple at row 53, column 102:
{{ visible_text(m.content) }}
{{- '/nothink' if (enable_thinking is defined and not enable_thinking and not visible_text(m.content).endswith("/nothink")) else '' -}}
But, it worked because "failed to parse chat template (defaulting to chatml)"
Edit2 : I made two modifications in the jinja template from this link, and it works in Claude code.
- .endswith() error
From:
{{- '/nothink' if (enable_thinking is defined and not enable_thinking and not visible_text(m.content).endswith("/nothink")) else '' -}}
To:
{%- set user_content = visible_text(m.content) -%}
{{ user_content }}
{{- '/nothink' if (enable_thinking is defined and not enable_thinking and not user_content.endswith("/nothink")) else '' -}}
- Removed (ensure_ascii=False)
{{ tool | tojson(ensure_ascii=False) }} → {{ tool | tojson }}
{{ tc.arguments | tojson(ensure_ascii=False) }} → {{ tc.arguments | tojson }}
I hope this helps someone.
I understand that Claude Code and Roo Code use XML format for tool invocation, and that the default format for GLM 4.5 is also XML.
However, when I use the JSON-style Jinja(https://pastebin.com/CfMw7hFS), Claude Code and Roo Code work well, whereas using the default XML-style Jinja results in errors.
I don’t understand why this happens. If anyone is familiar with this issue, please explain.
Edit:
I confirmed that when I only modify the modifications I mentioned above in the original template (XML Tool Call) of GLM 4.5,
tool calls work well when using roo code (XML Tool Call) in GLM 4.5 AIR running on llama.cpp.
Just
From GLM 4.5 original jinja:
{{ visible_text(m.content) }}
{{- '/nothink' if (enable_thinking is defined and not enable_thinking and not visible_text(m.content).endswith("/nothink")) else '' -}}
To:
{%- set temp_content = visible_text(m.content) %}
{{ temp_content }}
{{- '/nothink' if (enable_thinking is defined and not enable_thinking and not temp_content.endswith("/nothink")) else '' -}}
You can now use XML templates!