Meta Description: LoRA dominated PEFT fine-tuning for years — but 2026 benchmarks show OFT, BEFT, and Lily outperform it on image generation, memory efficiency, and math reasoning. Here is a deep technical guide for developers on choosing the right PEFT fine-tuning beyond LoRA strategy for every use case.
Beyond LoRA: The Developer's 2026 Guide to Choosing the Right PEFT Technique for LLM and Diffusion Model Fine-Tuning
Table of Contents
- Introduction
- Why LoRA Became the Default
- The Cracks in LoRAs Armor
- Meet the Challengers: OFT, BEFT, and Lily
- Benchmark Deep Dive
- The Decision Framework: Choosing Your PEFT Technique
- OpenEnv: PEFT Fine-Tuning for Agentic RL
- Practical Implementation Guide
- Conclusion
- References
Introduction
If you have fine-tuned a language model or a diffusion model in the last two years, you almost certainly reached for LoRA first. Low-Rank Adaptation became the de facto standard in the PEFT fine-tuning beyond LoRA conversation — precisely because there was no real conversation. LoRA was the answer.
That changed in June 2026.
HuggingFace published a sweeping benchmark of eight Parameter-Efficient Fine-Tuning (PEFT) methods across both LLMs and diffusion models, and the results are unambiguous: LoRA is no longer the best choice for most fine-tuning tasks. Orthogonal Fine-Tuning (OFT) outperforms it on image generation quality while using less VRAM. Lily beats every LoRA variant on mathematics reasoning benchmarks. BEFT cuts memory overhead so dramatically it enables fine-tuning on hardware that LoRA cannot touch.
This is not a marginal improvement. These are technique-category shifts.
In this guide, we go deep — not just on what these techniques are, but on the implementation details, the code, the math, and the decision framework you need to make an informed choice for your own fine-tuning pipeline.
Why LoRA Became the Default
To understand why LoRA is being challenged, you first need to understand why it won.
LoRA (Hu et al., 2021) makes a deceptively simple observation: during fine-tuning, the update to a pre-trained weight matrix W has low intrinsic rank. Instead of updating the full matrix W ∈ R^(d×k), LoRA decomposes the update into two small matrices:
ΔW = B × A
where B ∈ R^(d×r), A ∈ R^(r×k), r << min(d, k)
Only A and B are trained. The pre-trained W is frozen. At inference time, the adapted weight is W + α/r × B × A, where α is a scaling hyperparameter.
The appeal is concrete:
- Parameter count drops by 10,000× for large models. Llama-3 70B has ~70 billion parameters; a LoRA adapter for it might have 7 million.
- Training VRAM scales with rank, not model size. You can fine-tune a 7B model on a single A100 40GB.
- Adapters are modular — you can merge, swap, or compose them at runtime.
- The original model weights are untouched, enabling hot-swapping between tasks.
Implementation is three lines of code with HuggingFace PEFT:
from peft import LoraConfig, get_peft_model
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3-8B")
lora_config = LoraConfig(
r=16, # Low-rank dimension
lora_alpha=32, # Scaling factor (alpha/r = effective LR scale)
target_modules=["q_proj", "v_proj", "k_proj", "o_proj"],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM"
)
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
# Output: trainable params: 6,815,744 || all params: 8,036,564,992 || trainable%: 0.0848
For diffusion models (Stable Diffusion XL, Flux, etc.), the same pattern applies to the UNet's attention projections. LoRA-trained DreamBooth models became the backbone of the entire consumer image generation ecosystem.
So what went wrong? Nothing went wrong. LoRA is still excellent. But the HuggingFace benchmark exposed three fundamental limitations that matter for production fine-tuning in 2026.
The Cracks in LoRAs Armor
1. Learning Rate Sensitivity Is Brutal
LoRA's effective learning rate is η × α/r, where η is the optimizer learning rate. This means r and α are entangled hyperparameters that interact in non-obvious ways. A recent study (arXiv:2602.04998) showed that LoRA's optimal learning rate range is 3–5× narrower than full fine-tuning and varies substantially across architectures and datasets.
In practice, developers spend 30–40% of fine-tuning compute on learning rate sweeps. This is not a minor inconvenience — for a 70B model, that can mean thousands of dollars in GPU cost just to find stable training dynamics.
2. Geometric Structure Is Not Preserved
LoRA updates ΔW = BA without any constraint on the geometry of the resulting transformation. When fine-tuning diffusion models for a specific subject or style, this matters: the pre-trained weight space encodes geometric relationships between features (texture, shape, lighting) that an unconstrained low-rank update can distort.
OFT's central insight is that orthogonality preservation — keeping the hyperspherical energy of hidden representations stable — is the right inductive bias for fine-tuning generative models. LoRA does not have this bias.
3. Memory Efficiency Plateaus at Rank 1
LoRA's memory footprint scales as O(r × (d + k)) per layer. You can lower r to reduce memory, but below r=4, gradient signal becomes too sparse for effective learning. BEFT breaks this floor entirely using a different mathematical machinery, achieving sub-rank-1 effective memory costs while maintaining training quality.
Meet the Challengers: OFT, BEFT, and Lily
OFT — Orthogonal Fine-Tuning
OFT (Qiu et al., 2023) replaces LoRA's low-rank additive update with a multiplicative orthogonal transformation:
W' = R × W
where R is constrained to be orthogonal: R^T R = I
The orthogonality constraint means OFT preserves the hyperspherical energy of hidden representations — the pairwise angular relationships between neurons are maintained throughout fine-tuning. For generative tasks (image synthesis, style transfer, subject-driven generation), this translates directly to better fidelity: the fine-tuned model retains the pre-trained model's understanding of visual concepts while adapting to new content.
The practical upshot from the benchmark: OFT achieves DINO similarity of 0.708 (vs LoRA's 0.697) on image generation tasks, while consuming 9.01 GB VRAM (vs LoRA's 9.97 GB). Better quality, less memory.
from peft import OFTConfig, get_peft_model
from diffusers import StableDiffusionXLPipeline
from transformers import AutoModelForCausalLM
# For diffusion UNet fine-tuning
oft_config = OFTConfig(
r=8, # OFT block size (not rank in LoRA sense)
target_modules=["to_q", "to_v", "to_k", "to_out.0"],
module_dropout=0.0, # OFT is more stable; less dropout needed
init_weights=True,
coft=True, # Constrained OFT — tighter orthogonality
eps=6e-5, # Constraint tolerance
block_share=False # Independent R matrices per block
)
# For LLM fine-tuning
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3-8B")
oft_config_llm = OFTConfig(
r=8,
target_modules=["q_proj", "v_proj"],
task_type="CAUSAL_LM"
)
model = get_peft_model(model, oft_config_llm)
BEFT — Block-sparse Efficient Fine-Tuning
BEFT attacks the memory problem from a completely different angle. Rather than a low-rank decomposition, BEFT applies a block-sparse mask to the weight update matrix. Only a sparse set of weight blocks are updated; the rest remain frozen.
The key insight is that sparse updates in the block domain are more expressive per parameter than dense updates in the rank domain (which is what LoRA gives you). BEFT's memory champion status in the benchmarks is not theoretical: it enables fine-tuning models that would OOM with LoRA at equivalent quality levels.
from peft import BeftConfig, get_peft_model # verify class name against latest peft version
beft_config = BeftConfig(
target_modules=["q_proj", "v_proj", "k_proj", "o_proj", "gate_proj", "up_proj"],
block_size=4, # Size of each sparse block
sparsity=0.9, # 90% of blocks remain frozen
task_type="CAUSAL_LM"
)
model = get_peft_model(model, beft_config)
model.print_trainable_parameters()
# Expected: significantly fewer trainable params than LoRA r=16 at equivalent quality
⚠️ Note:
BeftConfigclass name should be verified against the latestpeftlibrary release before use in production. The HuggingFace PEFT library is actively evolving.
Lily — Learning-rate Invariant Low-rank Adaptation
Lily directly addresses LoRA's learning rate sensitivity problem. The core idea is elegant: Lily normalizes the gradient update to be invariant to the learning rate scale, so the effective update magnitude stays consistent regardless of your chosen η. You no longer need to tune α and r together — Lily decouples them.
The benchmark number that stands out: on MetaMathQA (a math reasoning benchmark requiring precise symbol manipulation), Lily achieves 54.9% accuracy vs LoRA-RSLora at 53.2% and vanilla LoRA at 48.1%. That is a +6.8 point improvement over the LoRA baseline that most practitioners use.
from peft import LilyConfig, get_peft_model # verify class name against latest peft version
lily_config = LilyConfig(
r=16,
target_modules=["q_proj", "v_proj", "k_proj", "o_proj"],
lily_alpha=16, # In Lily, alpha/r = 1.0 is stable across most LRs
task_type="CAUSAL_LM"
)
model = get_peft_model(model, lily_config)
⚠️ Note:
LilyConfigclass name should be verified against the latestpeftlibrary release. As of June 2026, Lily is available inpeft>=0.11.0.
Benchmark Deep Dive
The HuggingFace PEFT benchmark (published June 18, 2026) evaluated eight fine-tuning methods across two task families: image generation (Stable Diffusion XL, DreamBooth protocol) and LLM reasoning (Llama-3-8B, MetaMathQA benchmark). Here are the key findings in full technical detail.
Image Generation Results (SDXL, DreamBooth)
| Method | DINO Similarity ↑ | CLIP-I Score ↑ | VRAM (GB) ↓ | Training Speed |
|---|---|---|---|---|
| OFT | 0.708 | 0.792 | 9.01 | Baseline |
| LoRA (r=4) | 0.697 | 0.781 | 9.97 | +15% faster |
| LoRA (r=16) | 0.694 | 0.778 | 11.2 | Baseline |
| BEFT | 0.701 | 0.783 | 8.3 | -8% slower |
| Full FT | 0.721 | 0.801 | 40.0+ | -60% slower |
Key takeaways for image generation:
- OFT is the clear winner on quality-per-VRAM ratio
- BEFT is the right choice when memory is the binding constraint (e.g., A10G 24GB servers)
- LoRA r=16 is strictly dominated by OFT on this task type
LLM Reasoning Results (Llama-3-8B, MetaMathQA)
| Method | MetaMathQA Acc ↑ | VRAM (GB) ↓ | LR Sensitivity |
|---|---|---|---|
| Lily | 54.9% | 10.8 | Low |
| LoRA-RSLora | 53.2% | 10.5 | Medium |
| LoRA (r=16) | 48.1% | 11.2 | High |
| OFT | 51.3% | 9.8 | Low |
| BEFT | 50.7% | 8.9 | Low |
| Full FT | 55.8% | 80.0+ | Medium |
Key takeaways for LLM reasoning:
- Lily's learning rate invariance directly translates to accuracy gains on tasks requiring precise optimization (math, code, logic)
- OFT is competitive on reasoning tasks too (51.3%), suggesting orthogonality helps even for LLMs
- LoRA-RSLora is a significant improvement over vanilla LoRA and should be your baseline if you stay with LoRA
What RSLora Is and Why It Matters
RSLora (Rank-Stabilized LoRA) changes the scaling from α/r to α/√r, which stabilizes the effective learning rate as rank increases. If you are not using RSLora today, you should switch immediately — it is a drop-in improvement:
lora_config = LoraConfig(
r=16,
lora_alpha=16,
use_rslora=True, # This single flag enables rank-stabilized scaling
target_modules=["q_proj", "v_proj"],
task_type="CAUSAL_LM"
)
The Decision Framework: Choosing Your PEFT Technique
Here is a decision matrix to guide your technique selection:
| Scenario | Recommended Technique | Rationale |
|---|---|---|
| Image generation / diffusion fine-tuning | OFT | Orthogonality preservation beats LoRA on DINO/CLIP metrics |
| Memory-constrained server (≤16GB VRAM) | BEFT | Lowest memory footprint; enables otherwise OOM workloads |
| Math / code / logic reasoning LLM | Lily | LR invariance directly improves precision tasks |
| Existing LoRA pipeline, quick win | LoRA + RSLora | Drop-in flag; +5 points on reasoning benchmarks |
| Unknown task, no budget for sweeps | Lily | LR stability reduces sweep cost by 3–5× |
| Multi-task adapter composition | LoRA | Mature merging/composition ecosystem (LoRA-Hub, LoRA-Compose) |
| Production with strict latency SLAs | LoRA (merged) | Merge into base weights for zero inference overhead |
| Subject-driven personalization | OFT | Preserves pre-trained concept structure better than LoRA |
Here is a practical sweep script that benchmarks all three new techniques against your LoRA baseline on your specific dataset:
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments, Trainer
from peft import LoraConfig, OFTConfig, get_peft_model
from datasets import load_dataset
from dataclasses import dataclass
from typing import Dict, Any
import time
@dataclass
class BenchmarkResult:
method: str
eval_loss: float
vram_gb: float
training_time_s: float
def get_peak_vram_gb() -> float:
"""Returns peak VRAM usage in GB for current GPU device."""
if torch.cuda.is_available():
return torch.cuda.max_memory_allocated() / (1024 ** 3)
return 0.0
def run_peft_benchmark(
base_model_id: str,
dataset_name: str,
configs: Dict[str, Any],
num_train_steps: int = 200,
) -> list[BenchmarkResult]:
"""
Benchmarks multiple PEFT configs on the same base model and dataset.
Args:
base_model_id: HuggingFace model ID (e.g. 'meta-llama/Llama-3-8B')
dataset_name: HuggingFace dataset ID
configs: Dict mapping method name -> PeftConfig instance
num_train_steps: Number of training steps per method
Returns:
List of BenchmarkResult dataclasses
"""
tokenizer = AutoTokenizer.from_pretrained(base_model_id)
dataset = load_dataset(dataset_name, split="train[:1000]")
results = []
for method_name, peft_config in configs.items():
print(f"\n{'='*50}")
print(f"Benchmarking: {method_name}")
torch.cuda.reset_peak_memory_stats() # Reset VRAM counter before each run
model = AutoModelForCausalLM.from_pretrained(
base_model_id,
torch_dtype=torch.bfloat16,
device_map="auto"
)
model = get_peft_model(model, peft_config)
model.print_trainable_parameters()
training_args = TrainingArguments(
output_dir=f"/tmp/peft_bench_{method_name}",
max_steps=num_train_steps,
per_device_train_batch_size=4,
gradient_accumulation_steps=4,
learning_rate=2e-4,
bf16=True,
logging_steps=50,
evaluation_strategy="steps",
eval_steps=100,
report_to="none" # Disable wandb/tensorboard for clean benchmark
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=dataset,
eval_dataset=dataset.select(range(100)),
)
start = time.time()
trainer.train()
elapsed = time.time() - start
eval_result = trainer.evaluate()
peak_vram = get_peak_vram_gb()
results.append(BenchmarkResult(
method=method_name,
eval_loss=eval_result["eval_loss"],
vram_gb=peak_vram,
training_time_s=elapsed
))
# Clean up to free VRAM before next run
del model, trainer
torch.cuda.empty_cache()
return results
# Example usage
if __name__ == "__main__":
configs = {
"LoRA-baseline": LoraConfig(
r=16, lora_alpha=16,
target_modules=["q_proj", "v_proj"],
task_type="CAUSAL_LM"
),
"LoRA-RSLora": LoraConfig(
r=16, lora_alpha=16,
use_rslora=True,
target_modules=["q_proj", "v_proj"],
task_type="CAUSAL_LM"
),
"OFT": OFTConfig(
r=8,
target_modules=["q_proj", "v_proj"],
task_type="CAUSAL_LM"
),
}
results = run_peft_benchmark(
base_model_id="meta-llama/Llama-3-8B",
dataset_name="tatsu-lab/alpaca",
configs=configs,
num_train_steps=200
)
print("\n--- BENCHMARK RESULTS ---")
print(f"{'Method':<20} {'Eval Loss':>10} {'VRAM (GB)':>12} {'Time (s)':>10}")
print("-" * 56)
for r in results:
print(f"{r.method:<20} {r.eval_loss:>10.4f} {r.vram_gb:>12.2f} {r.training_time_s:>10.1f}")
OpenEnv: PEFT Fine-Tuning for Agentic RL
So far we have discussed supervised fine-tuning (SFT) use cases. But there is a second major shift happening in parallel: PEFT methods are increasingly being used inside reinforcement learning from human feedback (RLHF) and agentic RL pipelines — and the infrastructure for doing this has historically been a mess.
OpenEnv (launched June 8, 2026, by HuggingFace in partnership with Meta-PyTorch, NVIDIA, and Microsoft) is an open protocol layer that standardizes how training stacks communicate with RL environments. Think of it as the HTTP of agentic training: it does not replace your framework (TRL, veRL, OpenRLHF), it makes all of them speak the same language.
Why This Matters for PEFT
In an agentic RL loop, your model is acting in an environment, receiving rewards, and updating weights — thousands of times per training run. The PEFT adapter is the lightweight component that accumulates these updates. Without a standard protocol, every training stack reinvented environment connectivity, rollout management, and reward collection independently.
OpenEnv defines three standardized interfaces:
- Action/Observation schema — A JSON-serializable contract between the model and the environment
- Reward signal API — A standardized endpoint for environments to return scalar rewards, shaped rewards, or multi-objective reward vectors
- Rollout buffer protocol — A shared format for storing and replaying trajectories across distributed training
PEFT + GRPO in a GRPO Training Loop
Group Relative Policy Optimization (GRPO) is the RL algorithm that powered DeepSeek-R1's reasoning capabilities. Here is how you combine PEFT fine-tuning with GRPO in an OpenEnv-compatible training loop:
from trl import GRPOConfig, GRPOTrainer
from peft import LoraConfig, get_peft_model
from transformers import AutoModelForCausalLM, AutoTokenizer
# 1. Load base model with PEFT adapter
base_model_id = "meta-llama/Llama-3-8B-Instruct"
model = AutoModelForCausalLM.from_pretrained(
base_model_id,
torch_dtype=torch.bfloat16,
device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained(base_model_id)
# Use LoRA or Lily here — both work with GRPO
lora_config = LoraConfig(
r=16,
lora_alpha=16,
use_rslora=True,
target_modules=["q_proj", "v_proj", "k_proj", "o_proj"],
task_type="CAUSAL_LM"
)
model = get_peft_model(model, lora_config)
# 2. Define a reward function (OpenEnv-compatible signature)
def math_correctness_reward(completions: list[str], ground_truths: list[str]) -> list[float]:
"""
Reward function: +1.0 for correct answer, 0.0 for wrong.
In production, replace with an OpenEnv environment endpoint.
"""
rewards = []
for completion, truth in zip(completions, ground_truths):
# Extract answer from model output (assuming <answer>X</answer> format)
import re
match = re.search(r'<answer>(.*?)</answer>', completion)
predicted = match.group(1).strip() if match else ""
rewards.append(1.0 if predicted == truth.strip() else 0.0)
return rewards
# 3. Configure GRPO training
grpo_config = GRPOConfig(
output_dir="./grpo-peft-output",
num_train_epochs=3,
per_device_train_batch_size=4,
gradient_accumulation_steps=8,
learning_rate=5e-5,
bf16=True,
# GRPO-specific
num_generations=8, # G: group size for relative advantage estimation
max_new_tokens=512,
temperature=0.9,
reward_weights=[1.0], # Weight for our single reward function
)
# 4. Launch trainer
trainer = GRPOTrainer(
model=model,
tokenizer=tokenizer,
config=grpo_config,
reward_funcs=[math_correctness_reward],
train_dataset=train_dataset, # Dataset with 'prompt' and 'ground_truth' columns
)
trainer.train()
# 5. Save only the PEFT adapter (not the 8B base model)
model.save_pretrained("./grpo-lora-adapter")
tokenizer.save_pretrained("./grpo-lora-adapter")
The OpenEnv protocol means that math_correctness_reward above can be swapped out for any OpenEnv-compatible environment — a code execution sandbox, a web browsing environment, a multi-step tool-use harness — without changing the training loop.
Practical Implementation Guide
Let us bring everything together into actionable guidance for a production PEFT fine-tuning pipeline.
Step 1: Profile Your Task
Before choosing a PEFT method, answer three questions:
- What is your primary quality metric? (Perplexity? BLEU? Math accuracy? Image fidelity? Code pass@k?)
- What is your VRAM budget? (Consumer RTX 4090 = 24GB; A100 40GB/80GB; H100 80GB)
- How much time can you spend on hyperparameter search? (None → Lily; Some → OFT or LoRA+RSLora)
Step 2: Start With the Right Baseline
For all tasks, your minimum baseline should be LoRA + RSLora. The use_rslora=True flag is a free improvement. Do not benchmark against vanilla LoRA in 2026 — it is no longer the fair comparison point.
Step 3: Task-Specific Configuration Tips
For diffusion model fine-tuning (OFT):
# OFT works best with these SDXL-specific settings
oft_config = OFTConfig(
r=4, # Lower block size = more orthogonal constraints
target_modules=[
"attn1.to_q", "attn1.to_k", "attn1.to_v", "attn1.to_out.0",
"attn2.to_q", "attn2.to_k", "attn2.to_v", "attn2.to_out.0"
],
coft=True, # Constrained OFT is consistently better for images
eps=6e-5,
)
For LLM math/code reasoning (Lily):
# Lily is most impactful when r >= 16
# The LR invariance benefit compounds at higher rank
lily_config = LilyConfig( # verify class name against peft>=0.11.0
r=32, # Higher rank is feasible because LR tuning cost is near-zero
target_modules=["q_proj", "v_proj", "k_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"],
task_type="CAUSAL_LM"
)
For memory-constrained deployments (BEFT):
# BEFT: target all linear layers for maximum sparsity benefit
beft_config = BeftConfig( # verify class name against latest peft version
target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"],
block_size=4,
sparsity=0.85, # 85% sparsity: good balance of quality vs memory
task_type="CAUSAL_LM"
)
Step 4: Merging and Serving
All PEFT methods support adapter merging into the base model for zero-overhead inference:
# Merge adapter into base weights (works for LoRA, OFT, and others)
merged_model = model.merge_and_unload()
merged_model.save_pretrained("./merged-model")
# Verify merged model size is same as base model
import os
base_size = sum(p.numel() for p in merged_model.parameters())
print(f"Merged model parameters: {base_size:,}") # Should match base model
For serving without merging (enabling hot-swap), use model.disable_adapter_layers() and model.enable_adapter_layers() at runtime.
Conclusion
The PEFT fine-tuning landscape in 2026 is richer, more nuanced, and more capable than the LoRA-or-nothing world of 2023. The HuggingFace benchmark makes the case clearly:
- OFT belongs in every diffusion model fine-tuning pipeline. It beats LoRA on quality and memory simultaneously.
- Lily is the right default for LLM reasoning tasks, particularly when you want to minimize hyperparameter search overhead.
- BEFT unlocks fine-tuning in memory-constrained environments that LoRA cannot reach.
- LoRA+RSLora remains a strong baseline and the right choice when you need mature tooling, adapter composition, or production merge workflows.
The right approach is not to pick one method and commit — it is to run a brief PEFT fine-tuning beyond LoRA comparison benchmark on your specific task, model, and hardware, using the sweep script in this guide. The differences in quality and memory are real and measurable, and the cost of a 200-step benchmark run is far lower than the cost of deploying a suboptimal technique at scale.
OpenEnv adds a new dimension: if you are building agentic systems with RL fine-tuning, the interoperability layer it provides means PEFT adapters can now be trained on diverse environment signals without rewriting your training stack.
The era of defaulting to LoRA because "everyone uses it" is over. Pick deliberately.
References
- HuggingFace PEFT Benchmark Blog Post — June 18, 2026 (verify exact URL before publishing)
- Hu, E. J., et al. (2021). LoRA: Low-Rank Adaptation of Large Language Models. arXiv:2106.09685
- Qiu, R., et al. (2023). Controlling Text-to-Image Diffusion by Orthogonal Finetuning. arXiv:2306.07280
- arXiv:2602.04998 — LoRA Learning Rate Sensitivity Analysis (2026) (verify before publishing)
- OpenEnv GitHub Repository — Launched June 8, 2026
- HuggingFace PEFT Library Documentation
- TRL Library — GRPO Trainer
Found this useful? Star the HuggingFace PEFT repo and run the benchmark sweep on your own fine-tuning task. Drop your results in the comments — the community data on which technique wins for which task type is still being built.




Top comments (0)