Instructions to use aixonlab/svg-slm-4b-lora with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use aixonlab/svg-slm-4b-lora with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="aixonlab/svg-slm-4b-lora") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("aixonlab/svg-slm-4b-lora", device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use aixonlab/svg-slm-4b-lora with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "aixonlab/svg-slm-4b-lora" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "aixonlab/svg-slm-4b-lora", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/aixonlab/svg-slm-4b-lora
- SGLang
How to use aixonlab/svg-slm-4b-lora 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 "aixonlab/svg-slm-4b-lora" \ --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": "aixonlab/svg-slm-4b-lora", "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 "aixonlab/svg-slm-4b-lora" \ --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": "aixonlab/svg-slm-4b-lora", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use aixonlab/svg-slm-4b-lora with Docker Model Runner:
docker model run hf.co/aixonlab/svg-slm-4b-lora
svg-slm-4b LoRA adapter (EXPERIMENTAL - does not beat frontier models)
A first-iteration LoRA fine-tune of Qwen/Qwen3.5-4B for text-to-SVG generation (icons, flat illustrations, line art, gradients, emoji, SMIL/CSS animation, scenes). This repo holds the LoRA adapter (r=32), training log and eval outputs; merged bf16 weights are in aixonlab/svg-slm-4b.
Honest summary. The project goal was to beat Claude Sonnet 5.5 at SVG generation. This checkpoint does not. It was trained for about 2 GPU-hours (207 optimizer steps, roughly 3,300 examples, about 4% of the dataset) under a hard $4 compute cap. In a blind pairwise evaluation it lost every comparison. Treat it as a baseline and starting point, not a replacement for a frontier model.
Evaluation
- Set: 60 prompts written for this project (icon 10, flat illustration 10, line art B/W 8, shaded/gradient 8, emoji 6, animated 10, complex scene 8). Baseline: Sonnet-written SVGs for each prompt. The 60 model generations are in
eval_outputs_v2.jsonand the judge output injudge_v2.jsonof the LoRA repo. - Judge: Claude Opus 5.5 (subagent), blind to which side was which, position randomized, scoring prompt adherence and visual quality from 1 to 10.
- Decoding: temperature 0.4, top-p 0.9, repetition penalty 1.06, max 6,000 new tokens, stop at
</svg>.
| Result | Value |
|---|---|
| Outputs that were a complete, renderable SVG | 26 / 60 (32 hit the 6,000-token cap without closing </svg>, mostly repetition loops or over-long path data; 2 rendered blank) |
| Blind judge wins, model vs Sonnet 5.5 (valid outputs only, n=26) | 0 / 26 |
| Mean judge score on those 26 | model 1.6 / 10, Sonnet 5.5 8.4 / 10 |
| Win rate over all 60 prompts (invalid counted as a loss) | 0 % |
Per category (valid outputs only) Sonnet won every comparison: icon 7/7, shaded 6/6, animated 5/5, line art 3/3, emoji 2/2, scene 2/2, flat illustration 1/1.
Caveats: the eval set is small and was created inside the same project; animations were judged on a static frame; a single judge model was used. An earlier decode (temperature 0.6, 3,500-token cap) gave only 20/60 valid outputs.
Known limitations
- Weak prompt adherence: outputs are often plausible-looking shapes that do not depict the request.
- Frequently fails to terminate and degenerates into repeated path fragments on long outputs.
- Complex scenes and animation are weakest. Training sequences were capped at 5,000 total tokens, which removed most "complex scene" examples.
- Only a small slice of the data was seen and there was no preference or RL stage.
Training
- Method: SFT with LoRA r=32 / alpha=64 on all attention and MLP projections (42.5M trainable parameters), bf16, learning rate 1e-4 with cosine decay, effective batch 16 (batch 1 x gradient accumulation 16), loss on assistant (SVG) tokens only, thinking disabled in the chat template. 207 steps; loss went from about 0.78 to about 0.70.
- Data:
aixonlab/svg-sft-v1, 78,620 license-filtered examples (Iconify permissive sets, SVG Repo permissive rows, Clker, OpenClipart, InternSVG SAgoge and SVG-Sophia). Only about 3.3k were seen. The dataset card lists sources, licenses and attribution (some rows are CC-BY). - Hardware: one RTX PRO 4500 Blackwell (32 GB) on Runpod. Training kernels fell back to slow PyTorch paths (
flash-linear-attentioninstalled,causal-conv1dnot), which held throughput to roughly 38-43 s/step.
Usage
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
from peft import PeftModel
base = "Qwen/Qwen3.5-4B"
tok = AutoTokenizer.from_pretrained(base)
model = AutoModelForCausalLM.from_pretrained(base, torch_dtype=torch.bfloat16, device_map="auto")
model = PeftModel.from_pretrained(model, "aixonlab/svg-slm-4b-lora").merge_and_unload()
msgs = [{"role": "user", "content": "flat icon of a red coffee mug with steam"}]
text = tok.apply_chat_template(msgs, tokenize=False, add_generation_prompt=True, enable_thinking=False)
ids = tok(text, return_tensors="pt", add_special_tokens=False).to(model.device)
out = model.generate(**ids, max_new_tokens=6000, do_sample=True, temperature=0.4, top_p=0.9,
repetition_penalty=1.06, stop_strings=["</svg>"], tokenizer=tok)
print(tok.decode(out[0][ids["input_ids"].shape[1]:], skip_special_tokens=True))
Extract the first <svg ...>...</svg> from the output and validate it before use. Animated SVGs need a browser to render, since resvg and CairoSVG ignore animation.
What would be needed to actually compete
More compute (a full epoch or more over the 78k examples, with fast linear-attention kernels), better captions than metadata-derived prompts, preference or RL training with a render-based reward, and a fix for early termination and repetition. This checkpoint demonstrates the pipeline end to end, not the end result.
License
Apache-2.0 for the weights (inherited from the base model). Training data carries per-row licenses (MIT, Apache-2.0, CC0, public domain, CC-BY-4.0, ISC, BSD, Unlicense). This is not legal advice; review the dataset card before commercial use.