Extends the Windows-gating work to the optional-skills/ tree. Every
SKILL.md that previously omitted the platforms: field now carries an
explicit declaration, which Hermes's loader (agent.skill_utils.
skill_matches_platform) honors to skip-load on incompatible OSes.
58 skills declared cross-platform (platforms: [linux, macos, windows]):
autonomous-ai-agents/blackbox, autonomous-ai-agents/honcho
blockchain/base, blockchain/solana
communication/one-three-one-rule
creative/blender-mcp, creative/concept-diagrams, creative/hyperframes,
creative/kanban-video-orchestrator, creative/meme-generation
devops/cli (inference-sh-cli), devops/docker-management
dogfood/adversarial-ux-test
email/agentmail
finance/3-statement-model, finance/comps-analysis, finance/dcf-model,
finance/excel-author, finance/lbo-model, finance/merger-model,
finance/pptx-author
health/fitness-nutrition, health/neuroskill-bci
mcp/fastmcp, mcp/mcporter
migration/openclaw-migration
mlops/accelerate, mlops/chroma, mlops/clip, mlops/guidance,
mlops/hermes-atropos-environments, mlops/huggingface-tokenizers,
mlops/instructor, mlops/lambda-labs, mlops/llava, mlops/modal,
mlops/peft, mlops/pinecone, mlops/pytorch-lightning, mlops/qdrant,
mlops/saelens, mlops/simpo, mlops/stable-diffusion
productivity/canvas, productivity/shop-app, productivity/shopify,
productivity/siyuan, productivity/telephony
research/domain-intel, research/drug-discovery, research/duckduckgo-search,
research/gitnexus-explorer, research/parallel-cli, research/scrapling
security/1password, security/oss-forensics, security/sherlock
web-development/page-agent
5 skills gated from Windows (platforms: [linux, macos]):
mlops/flash-attention - Flash Attention wheels are Linux-first; Windows
install requires building from source with CUDA
mlops/faiss - faiss-gpu has no Windows wheel; gate rather than
leak partial (faiss-cpu) support
mlops/nemo-curator - NVIDIA NeMo ecosystem has no first-class Windows path
mlops/slime - Megatron+SGLang RL stack is Linux-only in practice
mlops/whisper - openai-whisper + ffmpeg setup on Windows is
non-trivial; gate until Windows install stanza lands
Methodology: scanned every SKILL.md for Windows-hostile signals
(apt-get, brew, systemd, osascript, ptrace, X11 binaries, POSIX-only
Python APIs, Docker POSIX $(pwd) bind-mounts, explicit 'linux-only' /
'macos-only' text). 3 skills flagged as having hard signals on review:
docker-management and qdrant only had POSIX $(pwd) docker examples and
the tools themselves (Docker Desktop, Qdrant) run fine on Windows —
declared ALL. whisper had an apt/brew ffmpeg install path and nothing
else but the openai-whisper Windows install story is rough enough to
warrant gating.
Strict-over-lenient policy: when in doubt, gate. Easier to un-gate after
verified Windows support lands than to leak partial support that
manifests as mid-task failures for Windows users.
Parameter-efficient fine-tuning for LLMs using LoRA, QLoRA, and 25+ methods. Use when fine-tuning large models (7B-70B) with limited GPU memory, when you need to train <1% of parameters with minimal accuracy loss, or for multi-adapter serving. HuggingFace's official library integrated with transformers ecosystem.
1.0.0
Orchestra Research
MIT
peft>=0.13.0
transformers>=4.45.0
torch>=2.0.0
bitsandbytes>=0.43.0
linux
macos
windows
hermes
tags
Fine-Tuning
PEFT
LoRA
QLoRA
Parameter-Efficient
Adapters
Low-Rank
Memory Optimization
Multi-Adapter
PEFT (Parameter-Efficient Fine-Tuning)
Fine-tune LLMs by training <1% of parameters using LoRA, QLoRA, and 25+ adapter methods.
When to use PEFT
Use PEFT/LoRA when:
Fine-tuning 7B-70B models on consumer GPUs (RTX 4090, A100)
Need to train <1% parameters (6MB adapters vs 14GB full model)
Want fast iteration with multiple task-specific adapters
Deploying multiple fine-tuned variants from one base model
Use QLoRA (PEFT + quantization) when:
Fine-tuning 70B models on single 24GB GPU
Memory is the primary constraint
Can accept ~5% quality trade-off vs full fine-tuning
Use full fine-tuning instead when:
Training small models (<1B parameters)
Need maximum quality and have compute budget
Significant domain shift requires updating all weights
Quick start
Installation
# Basic installation
pip install peft
# With quantization support (recommended)
pip install peft bitsandbytes
# Full stack
pip install peft transformers accelerate bitsandbytes datasets
LoRA fine-tuning (standard)
fromtransformersimportAutoModelForCausalLM,AutoTokenizer,TrainingArguments,Trainerfrompeftimportget_peft_model,LoraConfig,TaskTypefromdatasetsimportload_dataset# Load base modelmodel_name="meta-llama/Llama-3.1-8B"model=AutoModelForCausalLM.from_pretrained(model_name,torch_dtype="auto",device_map="auto")tokenizer=AutoTokenizer.from_pretrained(model_name)tokenizer.pad_token=tokenizer.eos_token# LoRA configurationlora_config=LoraConfig(task_type=TaskType.CAUSAL_LM,r=16,# Rank (8-64, higher = more capacity)lora_alpha=32,# Scaling factor (typically 2*r)lora_dropout=0.05,# Dropout for regularizationtarget_modules=["q_proj","v_proj","k_proj","o_proj"],# Attention layersbias="none"# Don't train biases)# Apply LoRAmodel=get_peft_model(model,lora_config)model.print_trainable_parameters()# Output: trainable params: 13,631,488 || all params: 8,043,307,008 || trainable%: 0.17%# Prepare datasetdataset=load_dataset("databricks/databricks-dolly-15k",split="train")deftokenize(example):text=f"### Instruction:\n{example['instruction']}\n\n### Response:\n{example['response']}"returntokenizer(text,truncation=True,max_length=512,padding="max_length")tokenized=dataset.map(tokenize,remove_columns=dataset.column_names)# Trainingtraining_args=TrainingArguments(output_dir="./lora-llama",num_train_epochs=3,per_device_train_batch_size=4,gradient_accumulation_steps=4,learning_rate=2e-4,fp16=True,logging_steps=10,save_strategy="epoch")trainer=Trainer(model=model,args=training_args,train_dataset=tokenized,data_collator=lambdadata:{"input_ids":torch.stack([f["input_ids"]forfindata]),"attention_mask":torch.stack([f["attention_mask"]forfindata]),"labels":torch.stack([f["input_ids"]forfindata])})trainer.train()# Save adapter only (6MB vs 16GB)model.save_pretrained("./lora-llama-adapter")
QLoRA fine-tuning (memory-efficient)
fromtransformersimportAutoModelForCausalLM,BitsAndBytesConfigfrompeftimportget_peft_model,LoraConfig,prepare_model_for_kbit_training# 4-bit quantization configbnb_config=BitsAndBytesConfig(load_in_4bit=True,bnb_4bit_quant_type="nf4",# NormalFloat4 (best for LLMs)bnb_4bit_compute_dtype="bfloat16",# Compute in bf16bnb_4bit_use_double_quant=True# Nested quantization)# Load quantized modelmodel=AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.1-70B",quantization_config=bnb_config,device_map="auto")# Prepare for training (enables gradient checkpointing)model=prepare_model_for_kbit_training(model)# LoRA config for QLoRAlora_config=LoraConfig(r=64,# Higher rank for 70Blora_alpha=128,lora_dropout=0.1,target_modules=["q_proj","v_proj","k_proj","o_proj","gate_proj","up_proj","down_proj"],bias="none",task_type="CAUSAL_LM")model=get_peft_model(model,lora_config)# 70B model now fits on single 24GB GPU!
# Merge for deployment (no adapter overhead)merged_model=model.merge_and_unload()# Save merged modelmerged_model.save_pretrained("./llama-merged")tokenizer.save_pretrained("./llama-merged")# Push to Hubmerged_model.push_to_hub("username/llama-finetuned")
Multi-adapter serving
frompeftimportPeftModel# Load base with first adaptermodel=AutoPeftModelForCausalLM.from_pretrained("./adapter-task1")# Load additional adaptersmodel.load_adapter("./adapter-task2",adapter_name="task2")model.load_adapter("./adapter-task3",adapter_name="task3")# Switch between adapters at runtimemodel.set_adapter("task1")# Use task1 adapteroutput1=model.generate(**inputs)model.set_adapter("task2")# Switch to task2output2=model.generate(**inputs)# Disable adapters (use base model)withmodel.disable_adapter():base_output=model.generate(**inputs)
PEFT methods comparison
Method
Trainable %
Memory
Speed
Best For
LoRA
0.1-1%
Low
Fast
General fine-tuning
QLoRA
0.1-1%
Very Low
Medium
Memory-constrained
AdaLoRA
0.1-1%
Low
Medium
Automatic rank selection
IA3
0.01%
Minimal
Fastest
Few-shot adaptation
Prefix Tuning
0.1%
Low
Medium
Generation control
Prompt Tuning
0.001%
Minimal
Fast
Simple task adaptation
P-Tuning v2
0.1%
Low
Medium
NLU tasks
IA3 (minimal parameters)
frompeftimportIA3Configia3_config=IA3Config(target_modules=["q_proj","v_proj","k_proj","down_proj"],feedforward_modules=["down_proj"])model=get_peft_model(model,ia3_config)# Trains only 0.01% of parameters!
Prefix Tuning
frompeftimportPrefixTuningConfigprefix_config=PrefixTuningConfig(task_type="CAUSAL_LM",num_virtual_tokens=20,# Prepended tokensprefix_projection=True# Use MLP projection)model=get_peft_model(model,prefix_config)
# axolotl config.yamladapter:loralora_r:16lora_alpha:32lora_dropout:0.05lora_target_modules:- q_proj- v_proj- k_proj- o_projlora_target_linear:true# Target all linear layers
With vLLM (inference)
fromvllmimportLLMfromvllm.lora.requestimportLoRARequest# Load base model with LoRA supportllm=LLM(model="meta-llama/Llama-3.1-8B",enable_lora=True)# Serve with adapteroutputs=llm.generate(prompts,lora_request=LoRARequest("adapter1",1,"./lora-adapter"))
# Verify adapter is activeprint(model.active_adapters)# Should show adapter name# Check trainable parametersmodel.print_trainable_parameters()# Ensure model in training modemodel.train()
Quality degradation
# Increase rankLoraConfig(r=32,lora_alpha=64)# Target more modulestarget_modules="all-linear"# Use more training data and epochsTrainingArguments(num_train_epochs=5)# Lower learning rateTrainingArguments(learning_rate=1e-4)
Best practices
Start with r=8-16, increase if quality insufficient
Use alpha = 2 * rank as starting point
Target attention + MLP layers for best quality/efficiency
Enable gradient checkpointing for memory savings
Save adapters frequently (small files, easy rollback)