On this page

Research

PorTAL: Portable Task Adaptation for LoRA

··13 min read
Today, fine-tuning locks task expertise inside one model.When the next model arrives, you re-tune from scratch.PorTAL learns the core task fine-tuning once.Then cheaply transfers to unseen models, even across families.
PorTAL learns a shared task latent and decoder core on seen bases, then ports to new models by refitting only a thin per-base alignment.

Parameter-efficient fine-tuning (e.g. LoRA) adapts a frozen LLM to a task, but the resulting adapter is welded to one base model: when a new model is released, the adaptation must be re-learned from scratch. We study portable task adaptation — learning a task adaptation once, in a base-agnostic form, and transferring it to new frozen models by refitting only a small per-model component.

PorTAL at a glance

Qwen3-8B (unseen)

~98%

of per-task LoRA lift recovered

Gemma-3-4B (cross-family)

~94%

of per-task LoRA lift recovered

Calibration data

~2×

less data to match LoRA plateau

Cross-LoRA baseline

~14%

lift recovered on unseen 8B

Headline portability and data-efficiency results across unseen Qwen3-8B and cross-family Gemma-3-4B.

Concretely, we learn a base-agnostic task latent ztz_t together with a per-base hypernetwork decoder DbD_b that generates per-layer LoRA for a frozen base; to port to a new base we freeze ztz_t and the shared decoder core, and refit only a thin per-base alignment on a small amount of data.

This works both within a model family and, more strikingly, across model families, recovering most of the accuracy gain that a from-scratch per-task LoRA provides over the unadapted base. Freezing a task latent and shared decoder core learned on Qwen3-1.7B and 4B, then refitting only a thin per-base alignment, recovers ~98% of LoRA's lift on an unseen Qwen3-8B, and ~94% on Gemma-3, a different model family. Additionally the refit is data-efficient: PorTAL reaches the from-scratch-LoRA accuracy plateau with roughly half the calibration data, and at equal accuracy is consistently better-calibrated (lower held-out log-loss) than a from-scratch LoRA at every data size. It far outperforms transferring an existing adapter: a faithful Cross-LoRA baseline that aligns a strong source LoRA into the new model's activation space recovers only ~14% of the gain on the unseen 8B, versus our ~98% — learning a shared latent beats translating an existing adapter.

Introduction and motivation

New language models arrive at an accelerating pace: the number of notable foundation models released per year rose from 2 in 2020 to 9 (2021), 32 (2022), and 149 in 2023Stanford HAI — AI Index Report 20241, and by 2024–2025 the frontier had become so crowded that the Elo gap between the top and 10th-ranked model collapsed from 11.9% to 5.4% in a single yearStanford HAI — AI Index Report 20252. In practice, a stronger base model — often several — ships every few months.

Adapting a model to a task, however, is a per-model cost that does not amortize across these releases. A fine-tune — full or LoRA — is welded to one base model's weight space; when the next model ships, the adaptation must be redone on the new base. Parameter-efficient methods lowered the unit cost (a LoRA on a 7B model runs ~13kvs 1–3k vs ~12k for full fine-tuningAlloc Labs — The Hidden Cost of LLM Fine-Tuning3) but not its structure: you still pay data curation + a training run + evaluation once per (task, model), and full fine-tuning cost still scales with model size, which keeps growing.

The result is an economic treadmill: maintaining a portfolio of fine-tuned capabilities on the current frontier model costs roughly (cost-per-adaptation) × (#tasks) × (#model releases tracked). Because per-adaptation cost is roughly fixed while release cadence rises, this total grows over time — re-fine-tuning per model becomes the dominant, ever-growing cost of keeping a system specialized while also gaining the raw intelligence of each newer, smarter base.

Our contribution is a combination and framing rather than a wholly new primitive, so we position it against three lines of work and credit each.

Hypernetworks that generate LoRA for a single base. Text-to-LoRA (Charakorn et al., ICML 2025)5, SHINE (2026)6, and Profile-to-PEFT (2025)7 amortize per-task or per-user adaptation into a single forward pass, but target a fixed base and generalize across tasks or users, not across models (Text-to-LoRA explicitly leaves cross-model transfer open).

Generating LoRA across architectures. LoRAGen (2025)8 uses a structural embedding (latent + module/layer embeddings) to emit LoRA for different bases, but is trained by reconstructing existing LoRAs; we share its decoder shape yet train end-to-end on task loss, and crucially, freeze a shared task latent and a shared core, refitting only a thin per-base alignment to reach an unseen base.

Transferring an existing LoRA across models. Cross-LoRA (Xia et al., 2025)9, LoRA-X (2025)10, and CAST (2025)11 target the same goal we do, but by translating one already-trained adapter via subspace or activation-manifold alignment; we instead learn a base-agnostic latent and regenerate the adapter per base. Head-to-head this matters: a faithful Cross-LoRA (strong source + activation alignment, subsuming CAST) recovers ~14% of LoRA's lift on the unseen 8B versus our ~98% (§6.2).

In short, the pieces — hypernetwork→LoRA, cross-architecture generation, and cross-model transfer — all have prior art. Our contribution is combining them into a freeze the latent and a shared core, refit only a thin per-base alignment porting recipe, framed as a maintenance-cost answer to an accelerating model-release cadence and shown to dominate the adapter-transfer line empirically.

Background: LoRA and LoRA hypernetworks

LoRA.LoRA: Low-Rank Adaptation of Large Language Models (Hu et al., 2021)12 For a frozen weight WRdout×dinW \in \mathbb{R}^{d_{out}\times d_{in}}, LoRA learns a low-rank update ΔW=αrBA\Delta W = \tfrac{\alpha}{r} B A with ARr×dinA \in \mathbb{R}^{r\times d_{in}}, BRdout×rB \in \mathbb{R}^{d_{out}\times r}, rdr \ll d, applied as y=Wx+αrB(Ax)y = Wx + \tfrac{\alpha}{r} B(Ax). Only A,BA,B train.

LoRA hypernetworks. Rather than training (A,B)(A,B) directly, a hypernetwork generates them from a conditioning input. Text-to-LoRA trains a hypernetwork to emit a full LoRA for a single base model from a task-description embedding, end-to-end through the frozen base. This amortizes per-task optimization into one forward pass — but is single-base and generalizes across tasks, not across models. Separately, Cross-LoRA, LoRA-X, and CAST transfer a single existing LoRA across bases via SVD-subspace or activation-manifold alignment (per-task, training-free, no shared latent). Our design borrows the hypernetwork-generates-LoRA idea but targets the orthogonal axis — cross-base transfer of a shared, learned task representation.

Method

Let a frozen base bb have transformer layers =1,,Lb\ell = 1,\dots,L_b and adapted projections W,mRd,mout×dinW_{\ell,m} \in \mathbb{R}^{d^{out}_{\ell,m}\times d^{in}_{\ell}} for modules m{q_proj,v_proj}m \in \{q\_proj, v\_proj\} (we extend mm to all attention and MLP projections in the full-module variant.) Let θb\theta_b denote the frozen base parameters.

Task latent. Each task tt is represented by a base-agnostic latent ztRdzz_t \in \mathbb{R}^{d_z} (dz=256d_z = 256).

Per-base decoder (hypernetwork). A small network DbD_b maps the latent + a layer embedding ee_\ell to the LoRA factors of each (layer, module):

(A,m,B,m)=Db(zt,e,m),A,mRr×din,  B,mRd,mout×r(A_{\ell,m},\, B_{\ell,m}) = D_b(z_t, e_\ell, m), \qquad A_{\ell,m}\in\mathbb{R}^{r\times d^{in}_\ell},\; B_{\ell,m}\in\mathbb{R}^{d^{out}_{\ell,m}\times r}

Internally DbD_b computes a per-layer trunk with FiLM conditioning on ztz_t,

h=ϕ(W2[(1+γ(zt))ψ(W1[zt;e])+β(zt)]),h_\ell = \phi\big(W_2\,\big[(1+\gamma(z_t))\odot \psi(W_1[z_t; e_\ell]) + \beta(z_t)\big]\big),

then per-module heads emit low-rank factors that a per-base linear alignment maps to (A,m,B,m)(A_{\ell,m}, B_{\ell,m}) (the Canonical decoder below), with the BB-path zero-initialized so ΔW,m=0\Delta W_{\ell,m}=0 at start (training begins from the clean base). The generated adapter is injected as a standard LoRA delta:

y,m=W,mx+αrB,m(A,mx).y_{\ell,m} = W_{\ell,m}\,x + \tfrac{\alpha}{r}\, B_{\ell,m}\,(A_{\ell,m}\,x).

Canonical decoder — a portable factorization. To make porting cheap, DbD_b factors into a large base-agnostic core, shared across all bases, plus a thin per-base alignment. The core maps the latent and layer embedding to low-rank factors in a fixed canonical width dcd_c that is independent of any base's dimensions; the per-base alignment is a learned per-layer embedding plus a linear map (A=A^PinA = \hat A\,P^{in}, B=PoutB^B = P^{out}\hat B) projecting those canonical factors into the target base's actual per-module dimensions. The shared core is trained once on the seen bases; porting to a new base reuses the core verbatim and fits only the thin linear alignment — a small, near-linear cross-model map.

Objective (source training). Only {zt}\{z_t\} and DbD_b are trainable; θb\theta_b is frozen. We minimize the gold-continuation NLL (loss only on answer tokens):

min{zt},Db  tE(x,y)Dt[logpθbDb(zt)(yx)].\min_{\{z_t\},\, D_b}\; \sum_{t}\, \mathbb{E}_{(x,y)\sim \mathcal{D}_t}\big[-\log p_{\,\theta_b\,\oplus\, D_b(z_t)}(y \mid x)\big].

Multi-task training uses balanced per-task steps with EMA loss-normalization (without it, hard tasks collapse to chance).

Shared latent across bases. For a set of seen bases B\mathcal{B}, we share both {zt}\{z_t\} and the base-agnostic core across all bases, keeping only a per-base alignment, and optimize bBtLb,t\sum_{b\in\mathcal{B}}\sum_t \mathcal{L}_{b,t}. Naively, a small base monopolizes the shared latent's gradient; we apply gradient-norm balancing on ztz_t, rescaling each base's accumulated gradient on ztz_t to equal norm before the optimizer step.

Portability (the transfer step). Given an unseen base bb', we freeze {zt}\{z_t\} and the shared core, and fit only the thin per-base alignment of a fresh decoder DbD_{b'} on a small calibration set:

minDb  tE(x,y)Dtcal[logpθbDb(zt)(yx)].\min_{D_{b'}}\; \sum_t \mathbb{E}_{(x,y)\sim \mathcal{D}^{cal}_t}\big[-\log p_{\,\theta_{b'}\,\oplus\, D_{b'}(z_t)}(y\mid x)\big].
PorTAL portability refit
Input: frozen task latents {z_t}, shared decoder core, unseen base b', calibration sets D_t^cal
1Initialize fresh per-base alignment for decoder D_{b'}
2freeze {z_t} and shared decoder core
3for epoch = 1 to 5 do
4Sample balanced batches from ∪_t D_t^cal
5(A, B) ← D_{b'}(z_t, e_ℓ, m) for each layer/module
6Minimize gold-continuation NLL on θ_{b'} ⊕ generated LoRA
7update only per-base alignment parameters
Porting reuses the task latent and shared core verbatim; only the thin linear alignment is refit on a handful of examples per task.
Porting freezes the task latent and shared decoder core; only the thin per-base alignment is refit on calibration data.

Experimental setup

Tasks (14, standard multiple-choice). TruthfulQA, RTE, CB, COPA, WiC, WSC (SuperGLUE + TruthfulQA; higher-headroom), and BoolQ, ARC-Easy, ARC-Challenge, HellaSwag, OpenBookQA, WinoGrande, CommonsenseQA, SciQ (broader/bigger-eval).

Metric. Length-normalized log-likelihood over choices (acc_norm); we also report held-out log-loss (token-mean NLL of the gold continuation). §6.1–6.3 use best-epoch held-out selection (per-epoch eval) while §6.4 uses final-epoch eval. All are 3-seed means ± std.

Data. Up to 2,000 examples/task — a hard cap applied to both source training and the per-base alignment refit (some smaller tasks have fewer). §6.1–6.3 fit on the full 2,000/task; the data-efficiency study (§6.4) shows far fewer suffices. Evaluation sets range from 56 (CB) to 1,000 (BoolQ/WinoGrande/CSQA/SciQ); ~7,200 eval examples total on the 14-task suite.

Models. Seen bases: Qwen3-1.7B, Qwen3-4B. Unseen bases: Qwen3-8B (same family), Gemma-3-4B (different family). Per-task LoRA baselines: rank 16 on q/k/v/o + MLP. LoRA Hypernet/PorTAL (§6.1–6.3): rank 8 on q/v, dz=256d_z=256.

Experiments reported. (i) LoRA Hypernet vs per-task LoRA; (ii) portability to unseen bases within and across families; (iii) data-efficiency of the per-base alignment refit.

Results

Source base: LoRA Hypernet matches per-task LoRA

Source base: LoRA Hypernet vs per-task LoRA (Qwen3-4B, 14 tasks)
MethodAvg acc_norm
Base0.627
Per-task LoRA0.765 ± 0.003
LoRA Hypernet (joint z, D_4B)0.757 ± 0.003
On Qwen3-4B across 14 tasks, a jointly trained hypernetwork recovers ~94% of per-task LoRA's average lift and matches or beats it on 6/14 tasks (RTE, CB, COPA, WiC, ARC-Easy, CommonsenseQA).

We first confirm that a hypernetwork — a learned task latent zz and the decoder, trained jointly on the source base — can match per-task LoRAs trained independently on the same base. It can: the generated LoRA Hypernet recovers ~94% of per-task LoRA's lift on average.

Within-family portability: unseen Qwen3-8B

Within-family portability on unseen Qwen3-8B (14 tasks)
Method (on unseen 8B)Avg acc_normRecovered lift
Base-8B (floor)0.667
Per-task 8B LoRA (ceiling)0.795 ± 0.004100%
Cross-LoRA transfer0.685 ± 0.001~14%
LoRA Hypernet (native 8B)0.785 ± 0.002~92%
PorTAL (frozen z, refit D_8B)0.792 ± 0.004~98%
Refitting only the per-base alignment on an unseen Qwen3-8B recovers ~98% of from-scratch LoRA's lift — far above a faithful Cross-LoRA transfer baseline at ~14%.

We then test the central portability claim: a latent and core learned on the seen bases should port to an unseen base by refitting only the thin alignment. It does — on an unseen Qwen3-8B, refitting only the per-base alignment recovers ~98% of the from-scratch LoRA's lift, reaching 0.792 against the 0.795 LoRA ceiling and far above the best cross-model transfer baseline. Freezing the latent is free, not a tax: training it natively on 8B from scratch reaches 0.785 ± 0.002 (~92%), statistically on par with the ported latent, so reusing a latent learned on other models costs essentially no quality while sparing the cost of re-deriving it per base.

Cross-family portability

Cross-family portability (14 tasks)
Unseen targetBasePer-task LoRAPorTALRecovered lift
Gemma-3-4B0.5950.778 ± 0.0040.767 ± 0.004~94%
The same Qwen-trained frozen latent ports to Gemma-3 — a different family, tokenizer, and architecture — recovering ~94% of its from-scratch LoRA lift via only a thin per-base map.

Finally, the cross-family test: does the same Qwen-trained frozen latent port to a different model family, not just a larger Qwen? It does — on Gemma-3, refitting only the lightweight per-base alignment recovers ~94% of its from-scratch LoRA's lift, so cross-family transfer is nearly lossless.

Data efficiency: PorTAL vs from-scratch LoRA

We hypothesize that PorTAL amortizes task adaptation: a latent and core learned once on the seen bases should make every subsequent model cheap to adapt, so porting to a new base needs far less data than training a LoRA from scratch there. We test this on the unseen Qwen3-8B, sweeping the refit-set size for three methods: PorTAL q/v r8, PorTAL full r8, and a separate per-task r16-full LoRA. All use the same per-size schedule and eval over 3 seeds, reporting final-epoch acc and log-loss. Raw 14-task averages use a base-8B floor acc of 0.667 and log-loss of 3.819.

Data efficiency: accuracy vs calibration size (unseen Qwen3-8B)

PorTAL q/v r8 reaches the from-scratch LoRA accuracy plateau (~0.77) at ~500 examples/task; from-scratch r16-full LoRA needs ~1,000. 3-seed means on unseen Qwen3-8B.

We find PorTAL is substantially more data-efficient. It reaches the strongest from-scratch LoRA's ~0.77 accuracy max with roughly 2× less calibration data: PorTAL q/v r8 hits that max at ~500 examples/task and full r8 at ~750, while from-scratch r16-full LoRA only settles there around ~1,000. PorTAL even ends slightly above it at the high end, 0.769 vs 0.762 at 2,000. Because the frozen base dominates per-step cost, reaching the target with half the data is also roughly half the adaptation FLOPs — the amortization we set out to test, since the latent and core are paid for only once.

PorTAL is also better-calibrated, with lower held-out log-loss than from-scratch LoRA at every data size. We read this as a calibration effect rather than a separate efficiency gain: held-out NLL penalizes overconfidence and a smaller adapter makes gentler logit edits, so the gap tracks adapter capacity.

Future work

Capacity competition on a cluster of hard tasks. With best-epoch selection most tasks recover (10/14 reach ~80–110% of LoRA's lift), but a small cluster of harder commonsense/knowledge tasks underfits — OpenBookQA (~42% of lift), WinoGrande (~57%), HellaSwag (~61%) — the most-distinct tasks losing the shared rank-8 decoder's gradient competition. This is an optimization limit, not a capacity one: a rank-16 generated adapter did not help (it regressed and merely shifted which task starved). In the future we hope to pursue better multi-task optimization (per-task capacity, curriculum), or a small per-task residual on top of the shared decoder.

Amortized text-description variant. A natural extension replaces the free per-task latent with an encoder over a task description (zt=E(emb(desct))z_t = E(\mathrm{emb}(\text{desc}_t))), so a brand-new task could be adapted zero-shot from its description alone (à la Text-to-LoRA), with no per-task training. We leave a full study to future work.

Other directions. Larger and instruction/generation tasks beyond multiple-choice; and theory on when a frozen latent suffices vs. when base-specific adaptation is required.

Appendix A — Architecture and training details

Architecture

Concrete configuration and dimensions for the §4 decoder:

  • Task latent ztz_t: 256-d (a free per-task vector; or the encoder output in the amortized variant).
  • Layer embedding ee_\ell: learned nn.Embedding(L, 32) — breaks symmetry so one decoder yields a different adapter per layer.
  • Trunk: Linear(256+32 → 512), GELU; FiLM modulate ((1+γ)h+β(1+\gamma)\odot h + \beta, with γ,β\gamma,\beta linear in ztz_t); Linear(512 → 512), GELU.
  • Heads (one A- and one B-head per module m{q,v}m\in\{q,v\}): A-head Linear(512 → rdinr\cdot d^{in}) reshaped to [r,din][r,d^{in}]; B-head Linear(512 → doutrd^{out}\cdot r) reshaped to [dout,r][d^{out},r].
  • Adapter: rank r=8r=8 on q_proj/v_proj at every layer; scaling α/r=2\alpha/r=2 (α=16\alpha=16); injected by wrapping the module's real forward and adding scaling(xA)B\text{scaling}\cdot(xA^\top)B^\top.
  • Init: B-heads and FiLM γ,β\gamma,\beta zero-initialized, so the generated adapter is the identity (ΔW=0\Delta W=0) at start.
  • Per-base alignment: a learned per-layer embedding plus per-module linear maps (PinP^{in} projecting the canonical dcd_c factors to the base's input width, PoutP^{out} to its output width).
  • Parameters: the core holds the bulk; the latent table is 256 × #tasks.

Training and hyperparameters

Training and hyperparameters
SettingValue
ObjectiveGold-continuation NLL (answer tokens only); base frozen
OptimizerAdamW
LR (decoder / latent)1e-3 / 2e-3
Epochs / batch size5 / 4
Max train examples / task2,000 (prompt capped at 768 tokens)
Multi-task balancingBalanced per-task steps + EMA loss-normalization (0.9 / 0.1)
Multi-base balancingGradient-norm balancing on shared latent
Portability refit8–2,000 ex/task; pure epoch budget
Per-task LoRA baselinepeft, rank 16, alpha 32, lr 1e-4, 5 epochs, q/k/v/o + MLP
HardwareSingle NVIDIA B200 (per run)
Full training configuration for source training, multi-base sharing, and portability refit.

Appendix B — Metrics: recovered lift vs retention

We report recovered lift; prior cross-model-transfer papers (Cross-LoRA, CAST) instead report retention (a ratio of accuracies). For a method mm, unadapted base bb, and from-scratch per-task LoRA LL:

recovered lift=accmaccbaccLaccb,retention=accmaccL.\text{recovered lift} = \frac{\mathrm{acc}_m - \mathrm{acc}_b}{\mathrm{acc}_L - \mathrm{acc}_b}, \qquad \text{retention} = \frac{\mathrm{acc}_m}{\mathrm{acc}_L}.

Retention is near 100% whenever there is little headroom (accbaccL\mathrm{acc}_b \approx \mathrm{acc}_L) — the regime those papers operate in (their trained LoRA adds only ~1% over base), so it is not discriminative. We evaluate in a higher-headroom setting and therefore use recovered lift. For comparability, in retention terms our faithful Cross-LoRA reimplementation scores ~86% (within CAST's reported 85–95% band) while recovering only ~14% of the lift, whereas our porting scores ~99% retention / ~98% recovered lift — i.e. we win on both metrics, and the gap is only visible under the stricter one.

Research author — Ben Geist @b_geist

Want to keep up with our next AI experiments? Subscribe here and follow us on @RampLabs. We're also hiring across roles at Ramp.

Citation

Next