Qwen Coder 3B - n8n Workflow Generation (SFT)
A fine-tuned version of Qwen2.5-Coder-3B-Instruct specialized in generating n8n workflow JSON configurations from natural language descriptions.
Model Description
This model was fine-tuned using Supervised Fine-Tuning (SFT) with the TRL library to understand and generate n8n workflow structures. It can produce valid JSON workflow definitions including nodes, connections, and configuration parameters.
| Property | Value |
|---|---|
| Base Model | Qwen/Qwen2.5-Coder-3B-Instruct |
| Training Method | SFT (Supervised Fine-Tuning) |
| Parameters | 3B |
| Training Data | eclaude/n8n-workflows-sft |
| License | Apache 2.0 |
Intended Uses
Direct Use
- Generate n8n workflow JSON from natural language descriptions
- Assist developers in creating automation workflows
- Prototype workflow structures before manual refinement
Out-of-Scope Use
- Production-critical workflow generation without human review
- General-purpose code generation (use the base model instead)
- Non-n8n automation platforms
Quick Start
Installation
pip install transformers torch accelerate
Basic Inference
from transformers import AutoModelForCausalLM, AutoTokenizer
model_id = "eclaude/qwen-coder-3b-n8n-sft"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
model_id,
torch_dtype="auto",
device_map="auto"
)
prompt = "Create an n8n workflow that fetches data from a REST API every hour and sends a Slack notification"
messages = [
{"role": "system", "content": "You are an n8n workflow expert. Generate valid n8n workflow JSON configurations."},
{"role": "user", "content": prompt}
]
text = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
)
inputs = tokenizer([text], return_tensors="pt").to(model.device)
outputs = model.generate(
**inputs,
max_new_tokens=2048,
temperature=0.7,
top_p=0.9,
do_sample=True,
pad_token_id=tokenizer.eos_token_id
)
response = tokenizer.decode(outputs[0][inputs.input_ids.shape[1]:], skip_special_tokens=True)
print(response)
Streaming Generation
from transformers import AutoModelForCausalLM, AutoTokenizer, TextStreamer
model_id = "eclaude/qwen-coder-3b-n8n-sft"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
model_id,
torch_dtype="auto",
device_map="auto"
)
streamer = TextStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)
prompt = "Create a workflow to monitor a GitHub repository for new issues and create Trello cards"
messages = [
{"role": "system", "content": "You are an n8n workflow expert. Generate valid n8n workflow JSON configurations."},
{"role": "user", "content": prompt}
]
text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
inputs = tokenizer([text], return_tensors="pt").to(model.device)
_ = model.generate(
**inputs,
max_new_tokens=2048,
streamer=streamer,
temperature=0.7,
do_sample=True
)
Using with vLLM (Recommended for Production)
from vllm import LLM, SamplingParams
llm = LLM(model="eclaude/qwen-coder-3b-n8n-sft")
sampling_params = SamplingParams(
temperature=0.7,
top_p=0.9,
max_tokens=2048
)
prompt = """<|im_start|>system
You are an n8n workflow expert. Generate valid n8n workflow JSON configurations.<|im_end|>
<|im_start|>user
Create a workflow to sync Airtable records with a PostgreSQL database daily<|im_end|>
<|im_start|>assistant
"""
outputs = llm.generate([prompt], sampling_params)
print(outputs[0].outputs[0].text)
Quantized Inference (Low VRAM)
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
import torch
model_id = "eclaude/qwen-coder-3b-n8n-sft"
quantization_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_compute_dtype=torch.float16,
bnb_4bit_quant_type="nf4"
)
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
model_id,
quantization_config=quantization_config,
device_map="auto"
)
# Use same inference code as above
Training Details
Training Data
The model was fine-tuned on eclaude/n8n-workflows-sft, a curated dataset of n8n workflow examples with natural language descriptions.
Training Procedure
- Framework: TRL SFTTrainer
- Infrastructure: Hugging Face Jobs
- Precision: Mixed precision (bf16)
Limitations
- JSON Validity: Generated workflows may require manual validation and adjustment
- Node Coverage: Performance varies by n8n node type; common integrations (HTTP, Slack, GitHub) perform better than niche nodes
- Complex Workflows: Multi-branch workflows with complex logic may be incomplete
- Version Drift: n8n workflow schema evolves; generated JSON may need updates for newer n8n versions
- No Execution Testing: Outputs are not tested against a live n8n instance
Recommendations
- Always validate generated JSON before importing into n8n
- Use as a starting point, not a complete solution
- Review connection mappings and credentials placeholders
- Test workflows in a staging environment first
Example Output
Prompt: "Create a simple webhook trigger that logs incoming data"
Generated Workflow:
{
"name": "Webhook Logger",
"nodes": [
{
"parameters": {
"path": "webhook-log",
"responseMode": "onReceived",
"responseData": "allEntries"
},
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [250, 300]
},
{
"parameters": {
"functionCode": "console.log(JSON.stringify($input.all(), null, 2));\nreturn $input.all();"
},
"name": "Log Data",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [450, 300]
}
],
"connections": {
"Webhook": {
"main": [[{"node": "Log Data", "type": "main", "index": 0}]]
}
}
}
Citation
@misc{qwen-coder-n8n-sft-2025,
author = {eclaude},
title = {Qwen Coder 3B - n8n Workflow Generation (SFT)},
year = {2025},
publisher = {Hugging Face},
url = {https://huggingface.co/eclaude/qwen-coder-3b-n8n-sft}
}
Model Card Contact
For questions, issues, or contributions, please open a discussion on this repository or contact via Hugging Face.