Instructions to use SASVAAI/qwen38-27b-terraform with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use SASVAAI/qwen38-27b-terraform with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="SASVAAI/qwen38-27b-terraform") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] pipe(text=messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoProcessor, AutoModelForMultimodalLM processor = AutoProcessor.from_pretrained("SASVAAI/qwen38-27b-terraform") model = AutoModelForMultimodalLM.from_pretrained("SASVAAI/qwen38-27b-terraform", device_map="auto") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] inputs = processor.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=256) print(processor.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - PEFT
How to use SASVAAI/qwen38-27b-terraform with PEFT:
Task type is invalid.
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use SASVAAI/qwen38-27b-terraform 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 SASVAAI/qwen38-27b-terraform:Q4_K_M # Run inference directly in the terminal: llama cli -hf SASVAAI/qwen38-27b-terraform:Q4_K_M
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf SASVAAI/qwen38-27b-terraform:Q4_K_M # Run inference directly in the terminal: llama cli -hf SASVAAI/qwen38-27b-terraform:Q4_K_M
Build from source code
git clone https://github.com/ggml-org/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-app # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama serve -hf SASVAAI/qwen38-27b-terraform:Q4_K_M # Run inference directly in the terminal: ./build/bin/llama cli -hf SASVAAI/qwen38-27b-terraform:Q4_K_M
Use Docker
docker model run hf.co/SASVAAI/qwen38-27b-terraform:Q4_K_M
- Llama new
- LM Studio
- Jan
- vLLM
How to use SASVAAI/qwen38-27b-terraform with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "SASVAAI/qwen38-27b-terraform" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "SASVAAI/qwen38-27b-terraform", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/SASVAAI/qwen38-27b-terraform:Q4_K_M
- SGLang
How to use SASVAAI/qwen38-27b-terraform 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 "SASVAAI/qwen38-27b-terraform" \ --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": "SASVAAI/qwen38-27b-terraform", "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 "SASVAAI/qwen38-27b-terraform" \ --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": "SASVAAI/qwen38-27b-terraform", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Ollama
How to use SASVAAI/qwen38-27b-terraform with Ollama:
ollama run hf.co/SASVAAI/qwen38-27b-terraform:Q4_K_M
- Unsloth Desktop
- Pi
How to use SASVAAI/qwen38-27b-terraform with Pi:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf SASVAAI/qwen38-27b-terraform:Q4_K_M
Configure the model in Pi
# Install Pi: npm install -g @earendil-works/pi-coding-agent # Add to ~/.pi/agent/models.json: { "providers": { "llama-cpp": { "baseUrl": "http://localhost:8080/v1", "api": "openai-completions", "apiKey": "none", "models": [ { "id": "SASVAAI/qwen38-27b-terraform:Q4_K_M" } ] } } }Run Pi
# Start Pi in your project directory: pi
- Docker Model Runner
How to use SASVAAI/qwen38-27b-terraform with Docker Model Runner:
docker model run hf.co/SASVAAI/qwen38-27b-terraform:Q4_K_M
- Lemonade
How to use SASVAAI/qwen38-27b-terraform with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull SASVAAI/qwen38-27b-terraform:Q4_K_M
Run and chat with the model
lemonade run user.qwen38-27b-terraform-Q4_K_M
List all available models
lemonade list
- Hermes Agent
How to use SASVAAI/qwen38-27b-terraform with Hermes Agent:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf SASVAAI/qwen38-27b-terraform:Q4_K_M
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 SASVAAI/qwen38-27b-terraform:Q4_K_M
Run Hermes
hermes
- Atomic Chat
- OpenClaw
How to use SASVAAI/qwen38-27b-terraform with OpenClaw:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf SASVAAI/qwen38-27b-terraform:Q4_K_M
Configure OpenClaw
# Install OpenClaw: npm install -g openclaw@latest # Register the local server and set it as the default model: openclaw onboard --non-interactive --mode local \ --auth-choice custom-api-key \ --custom-base-url http://127.0.0.1:8080/v1 \ --custom-model-id "SASVAAI/qwen38-27b-terraform:Q4_K_M" \ --custom-provider-id llama-cpp \ --custom-compatibility openai \ --custom-text-input \ --accept-risk \ --skip-health
Run OpenClaw
openclaw agent --local --agent main --message "Hello from Hugging Face"
qwen38-27b-terraform
Writes Terraform (HCL) from a plain-language description of the infrastructure
you want. Merged fine-tune for engineers drafting .tf files across AWS, GCP,
Azure, Kubernetes and eleven other provider families.
This is a merged fine-tune of
Qwen/Qwen3.8-27B: the LoRA adapter
has been fused into the base weights with merge_and_unload(), so it loads as
an ordinary transformers checkpoint with no PEFT dependency. It was trained
with 8-bit-quantized-base LoRA via TRL SFT.
Model details
| Developed by | SASVA AI Model Cognition Labs(MCL) Team |
| Base model | Qwen/Qwen3.8-27B |
| Base parameters | 27.78B total โ 26.90B language model, 0.46B vision tower, 0.42B multi-token-prediction head |
| Architecture family | qwen3_5 (Qwen3_5ForConditionalGeneration) โ hybrid: Gated DeltaNet linear attention, with full GQA every 4th layer (full_attention_interval: 4), 64 layers |
| Adaptation | LoRA (r=64, alpha=128, dropout=0.05), merged into the base |
| Trainable modules | linear-attention layers: in_proj_qkv, in_proj_z, out_proj; full-attention layers: q_proj, k_proj, v_proj, o_proj; MLP: gate_proj, up_proj, down_proj โ 400 modules in all |
| Untouched | vision tower, MTP head, embeddings, lm_head, every norm |
| Training method | lora_8bit (8-bit quantized base, bf16 LoRA, bf16 compute) |
| Precision in this repo | bfloat16, unquantized |
| Weights | 3 safetensors shards, 55.6 GB total |
| Context length | 262,144 (base capability); trained at 8,192 |
| Language | English prompts, HCL targets |
| License | Apache-2.0, inherited from the base model |
The config here carries no quantization_config โ 8-bit was a
training-time choice, not a property of these weights.
Intended use
Direct use. Given a one-paragraph description of infrastructure, emit the
Terraform configuration that implements it: resource, data, variable,
output, provider and terraform blocks as needed, raw HCL with no prose and
no markdown fences.
The prompt format is part of the contract. The model was trained on one exact rendering; see How to get started. Prompting it as a general chat model will not reproduce its behaviour.
How to get started
Prompt format
The model uses the base model's ChatML template with thinking disabled. Training rendered each sample as (newlines shown literally):
<|im_start|>system
{SYSTEM}<|im_end|>
<|im_start|>user
{INSTRUCTION}
```
{PLAIN_LANGUAGE_DESCRIPTION}
```<|im_end|>
<|im_start|>assistant
<think>
</think>
{HCL}<|im_end|>
Three things follow from this, and all three bite in practice:
- The user turn is
instruction, then a blank line, then the description inside a fenced code block. The instruction names the provider family ("Write a Terraform configuration for AWS that satisfies the requirement below. Emit only HCL โ no explanation, no markdown fences."); the fenced block holds the intent. enable_thinking=Falseis required. Every training sample carried the empty<think>\n\n</think>block, so the trained generation prefix ends after</think>. The template's default (enable_thinking=True) stops at<think>instead and invites the model to reason โ off-contract, and not what the loss was computed against.- Use
apply_chat_template; do not hand-build the string.
System prompt
This is the exact system prompt the adapter was trained under, taken from the training configuration. Changing it moves the model off its trained contract.
You are a Terraform expert. Given a plain-language description of infrastructure, output the complete, valid Terraform HCL configuration (including any required terraform, provider, resource, data, variable, and output blocks) that implements it. Output raw HCL onlyโno markdown, no explanations, no commentary.
Loading it
from_pretrained requests files by name, so it fetches the config, tokenizer
and safetensors shards only โ the GGUF in this repo costs transformers users
nothing. If you instead download the repo by hand, filter it, or you will pull
all 72 GB:
hf download SASVAAI/qwen38-27b-terraform --exclude "*.gguf" --local-dir ./qwen38-27b-terraform
Requires a transformers build that knows model_type: qwen3_5. Note that
AutoModelForCausalLM cannot load this architecture โ use
AutoModelForImageTextToText, which is what the multimodal config maps to.
import torch
from transformers import AutoModelForImageTextToText, AutoTokenizer
MODEL = "SASVAAI/qwen38-27b-terraform"
tokenizer = AutoTokenizer.from_pretrained(MODEL)
model = AutoModelForImageTextToText.from_pretrained(
MODEL, dtype=torch.bfloat16, device_map="auto",
attn_implementation="flash_attention_2", # "sdpa" if flash-attn is unavailable
)
model.eval()
SYSTEM = (
"You are a Terraform expert. Given a plain-language description of "
"infrastructure, output the complete, valid Terraform HCL configuration "
"(including any required terraform, provider, resource, data, variable, "
"and output blocks) that implements it. Output raw HCL onlyโno markdown, "
"no explanations, no commentary."
)
instruction = (
"Write a Terraform configuration for AWS that satisfies the requirement "
"below. Emit only HCL โ no explanation, no markdown fences."
)
description = (
"Create a VPC named \"Ntier\" in the dev environment with a CIDR block "
"defined by the `vpc_range` variable."
)
messages = [
{"role": "system", "content": SYSTEM},
{"role": "user", "content": f"{instruction}\n\n```\n{description}\n```"},
]
text = tokenizer.apply_chat_template(
messages, tokenize=False, add_generation_prompt=True, enable_thinking=False,
)
enc = tokenizer(text, return_tensors="pt").to(model.device)
out = model.generate(**enc, max_new_tokens=2048, do_sample=False,
temperature=None, top_p=None, top_k=None,
pad_token_id=tokenizer.pad_token_id)
print(tokenizer.decode(out[0][enc["input_ids"].shape[-1]:], skip_special_tokens=True))
Run locally with Ollama
The Q4_K_M GGUF ships in this repo, so there is nothing to build. Either of these works:
# A. One command โ Ollama pulls the GGUF straight from this repo
ollama run hf.co/SASVAAI/qwen38-27b-terraform
# B. Or fetch the GGUF plus the Modelfile and build the tag locally
hf download SASVAAI/qwen38-27b-terraform \
--include "*Q4_K_M.gguf" "Modelfile" --local-dir .
ollama create qwen38-terraform -f Modelfile
ollama run qwen38-terraform
Either way you download 16.8 GB, not the 55.6 GB of bf16 safetensors โ Ollama only fetches the GGUF.
The two paths are not quite equivalent. ollama run hf.co/... never reads a
Modelfile. The Hub serves a GGUF repo to Ollama through its own
OCI-compatible registry: it picks the Q4_K_M GGUF as the model layer and
attaches this repo's params and system files as the
parameter and system-prompt layers. Those two files are kept byte-equivalent to
the Modelfile's PARAMETER lines and SYSTEM block, so both
routes land on the same greedy, system-prompted configuration. Path B is the one
to use if you want to edit any of it.
Requirements
Ollama v0.34.0 or newer, and a llama.cpp build at commit 7cf1c54 or later.
The GGUF declares architecture qwen35; older runtimes will refuse to load it.
Verified transcript
Built and run end-to-end on this host from the GGUF in this repo (Ollama v0.34.0, 1ร H200, 48 CPU threads):
ollama create qwen38-terraform -f Modelfile # real 1m1.888s
ollama show qwen38-terraform
Model
architecture qwen35
parameters 27.3B
context length 262144
embedding length 5120
quantization Q4_K_M
Capabilities
tools
thinking
completion
Parameters
num_ctx 8192
num_predict 2048
stop "<|im_end|>"
stop "<|endoftext|>"
temperature 0
top_k 1
Then a held-out validation prompt (an AWS VPC with counted subnets), through
/api/generate with "think": false and
"options": {"num_thread": 48}:
done_reason |
stop |
prompt_eval_count |
195 tokens |
prompt_eval_duration |
14.48 s |
eval_count |
137 tokens |
eval_duration |
2.14 s (โ64 tok/s, GPU-offloaded) |
load_duration |
12.23 s |
total_duration |
28.85 s |
Four things worth noting, all confirmed on this build:
prompt_eval_countis 195 โ the same count thetransformerstokenizer produces for the same system+user messages. TheModelfileSYSTEMblock plus the GGUF's embedded chat template reconstruct the training-time prompt exactly.eval_countis 137 โ the same number of tokens bf16 emitted for this prompt under greedy decoding.num_ctxis load-bearing. Ollama sizes the default context from available VRAM and on this host chose 262,144. TheModelfilepins 8,192 to matchMAX_SEQ_LENat training time.- Send
"think": false.ollama showlists athinkingcapability, which comes from the base model's template, not from this fine-tune. Training used an empty<think></think>block on every sample, so thinking-on is off contract. Thetoolscapability is likewise inherited and untrained here.
Building your own GGUF (optional)
Needed only if you want a quantization other than the shipped Q4_K_M.
git clone https://github.com/ggml-org/llama.cpp && cd llama.cpp
pip install -r requirements/requirements-convert_hf_to_gguf.txt
python convert_hf_to_gguf.py /path/to/qwen38-27b-terraform \
--outfile terraform-qwen38-27b-f16.gguf --outtype f16
cmake -B build && cmake --build build --config Release -j
./build/bin/llama-quantize terraform-qwen38-27b-f16.gguf \
qwen38-27b-terraform-Q4_K_M.gguf Q4_K_M
Measured on this repo's weights:
| Quant | Size on disk | BPW | Tensors |
|---|---|---|---|
f16 |
54,657,733,952 B โ 50.9 GiB | 16.00 | 866 |
Q4_K_M |
16,810,714,432 B โ 15.7 GiB | 4.92 | 866 |
llama-quantize reported model size = 52115.19 MiB โ quant size = 16021.46 MiB, in 137.4 s on 16 threads. Other K-quants land between these two;
the two rows above are the only ones actually built and run here, so they are
the only ones quoted.
The GGUF carries 866 tensors against 1,199 in the safetensors โ the
converter emits the text model only. The vision tower is a separate --mmproj
run and is not part of this repo's GGUF, which is consistent with the vision
tower never having been trained.
The MTP layer is not optional
This is the one step that fails silently if you build the merge yourself.
config.json declares mtp_num_hidden_layers: 1, and llama.cpp's converter
reads it: it sets qwen35.block_count = 65 (64 transformer layers + 1) and
remaps the 15 mtp.* tensors onto blk.64.*. If your merged checkpoint is
missing them, conversion still succeeds โ and then Ollama refuses to load:
check_tensor_dims: tensor 'blk.64.attn_norm.weight' not found
PEFT's merge_and_unload() followed by save_pretrained() drops the mtp.*
tensors, because they are not part of the wrapped LM graph. They are restored
verbatim from the base checkpoint in this repo's third shard โ an exact
operation, since the adapter contains no MTP weights to merge. Reloading the
spliced repo and re-running that prompt reproduced the pre-splice generation
token-for-token, so the splice does not perturb the language-model path.
ollama show reporting 27.3B rather than 26.9B is the quick check that the
layer is present.
Stop tokens
The Modelfile's explicit stop "<|im_end|>" / stop "<|endoftext|>" lines
are belt-and-braces. The completion above ended on done_reason: "stop" with
the model emitting <|im_end|> itself.
Quantization fidelity
That same prompt was run twice under greedy decoding (temperature 0 / top_k 1):
once against the bf16 safetensors in this repo via transformers, once against
the Q4_K_M GGUF via Ollama.
- Both emitted 137 tokens and both produced the same two resources with the same arguments.
- They are not byte-identical: 396 characters from bf16 against 398 from
Q4_K_M. The entire difference is two inserted blank lines, one before eachtags = {block. - Both pass
terraform validate(terraform 1.16.2, aws provider 6.64.0) with the three referenced variables declared.
One example is one example. Q4_K_M on this model stays on-task and on-format
here and changes whitespace. If generated HCL is going to be applied, run
terraform validate and terraform plan against it.
Training details
Data
| Train | 74,911 pairs |
| Validation | 4,004 pairs |
| Max sequence length | 8,192 tokens |
Each pair is one .tf file containing at least one resource block, paired
with a plain-language instruction. Provider mix:
| Provider | Train | Val |
|---|---|---|
| AWS | 45,806 | 2,378 |
| Google Cloud | 8,588 | 506 |
| Azure | 8,546 | 473 |
| Kubernetes | 3,540 | 228 |
| OCI | 2,111 | 115 |
| Alibaba Cloud | 1,273 | 46 |
| GitHub | 882 | 48 |
| DigitalOcean | 808 | 42 |
| IBM Cloud | 713 | 45 |
| Yandex | 685 | 36 |
| Vault | 577 | 19 |
| Docker | 468 | 24 |
| OpenStack | 362 | 19 |
| vSphere | 283 | 17 |
| Cloudflare | 269 | 8 |
Method
8-bit QLoRA (bitsandbytes load_in_8bit) with a LoRA adapter over the
language model only. Supervised fine-tuning on completions and prompts together
โ standard causal LM loss over the full rendered sequence. 8 ร H200,
torchrun --nproc_per_node 8.
The adapter targets the ten projection names this architecture actually uses โ
in_proj_qkv, in_proj_z, out_proj (Gated DeltaNet linear-attention layers),
q_proj, k_proj, v_proj, o_proj (the full-attention layers, every 4th),
and gate_proj, up_proj, down_proj (MLP). That resolves to 400 modules,
all in the language model, none in the vision tower. The vision tower and the
MTP layer were not trained.
Final hyperparameters
lora_r |
64 |
lora_alpha |
128 |
lora_dropout |
0.05 |
learning_rate |
2e-4 |
lr_scheduler_type |
cosine |
num_train_epochs |
2 |
per_device_train_batch_size |
1 |
gradient_accumulation_steps |
4 |
| Effective batch size | 32 (1 ร 4 ร 8 GPUs) |
warmup_ratio |
0.05 |
weight_decay |
0.01 |
max_length |
8,192 |
optim |
adamw_torch |
max_grad_norm |
1.0 |
seed |
42 |
| Precision | bf16, gradient checkpointing on, sample packing off |
| Total optimizer steps | 4,682 |
DoRA, rsLoRA, LoRA+, NEFTune, Liger kernels and PiSSA/LoftQ init were all available and all left off.
Observed training metrics
train_loss |
0.33363042362527634 |
eval_loss |
0.3532276451587677 |
train_runtime |
37,262.78 s (~10 h 21 m) |
train_samples_per_second |
4.021 |
train_steps_per_second |
0.126 |
total_flos |
1.9212762900531773e+19 |
Final train mean_token_accuracy |
0.9217 |
Final eval mean_token_accuracy |
0.9093 |
| Tokens seen | 120,749,136 |
Evaluation
eval_loss = 0.352946, measured on these merged bf16 weights over the
full 4,004-row held-out validation split.
This is a teacher-forced loss: the model is scored on how well it predicts the reference HCL token by token, with the reference supplied as context.
Environmental impact
Reported rather than estimated, since the hardware is shared and per-job power was not instrumented:
| Hardware | 8 ร NVIDIA H200 |
| Training runtime | 37,263 s (~10.35 h) |
total_flos |
1.92e+19 |
Carbon emitted was not measured; the grid region and PUE of the host are not known to the authors.
Framework versions
| PEFT | 0.18.1 |
| TRL | 1.0.0 |
| Transformers | 5.7.0.dev0 (git main) |
| PyTorch | 2.5.1+cu121 |
| Datasets | 4.8.4 |
| Tokenizers | 0.22.2 |
| Accelerate | 1.13.0 |
| bitsandbytes | 0.49.2 |
qwen3_5 is not in any stable transformers release as of 2026-09-23. A
git-main install is required to load this model.
Citation
Cite this model, the base model, the dataset and the training stack:
@misc{qwen38_27b_terraform_2026,
title = {qwen38-27b-terraform},
author = {{SASVA AI Model Cognition Labs (MCL) Team}},
year = {2026},
url = {https://huggingface.co/SASVAAI/qwen38-27b-terraform}
}
@misc{qwen38-27b,
title = {Qwen3.8-27B},
author = {Qwen Team},
year = {2026},
url = {https://huggingface.co/Qwen/Qwen3.8-27B}
}
@dataset{terrads,
title = {TerraDS: A Dataset of Terraform Infrastructure-as-Code},
year = {2026},
publisher = {Zenodo},
doi = {10.5281/zenodo.20339474}
}
@misc{trl,
title = {TRL: Transformer Reinforcement Learning},
author = {von Werra, Leandro and others},
year = {2020},
url = {https://github.com/huggingface/trl}
}
- Downloads last month
- 87