CSE Roadmap

Common tier · about 4 hours · 4 parts

Part 2 of 4 · 14 min read

Definitions

Covers: Definitions; The structure; Results; Design rules; Interview questions, with the follow-ups; Common mistakes; What the example does not do.

Definitions

LoRA (low-rank adaptation)

  • LoRA: freeze a weight matrix W and learn a low-rank update B A; use W + (alpha / r) B A.

Rank and alpha

  • Rank r: the inner dimension of the factorisation, which sets adapter size and capacity. alpha: a scale; the update is multiplied by alpha / r.

PEFT (parameter-efficient finetuning)

  • PEFT: finetuning methods that train a small number of added or selected parameters instead of all weights.

Adapter merging and multi-LoRA serving

  • Merging: adding B A into W before serving. Multi-LoRA serving: one frozen base with many swappable adapters.

Quantisation, block and absmax

  • Quantisation: storing numbers with fewer bits. Block: a group of weights sharing one scale. Absmax scaling: dividing a block by its largest absolute value so it fits [-1, 1].

NF4 and QLoRA

  • NF4 (NormalFloat-4): a 4-bit format whose levels follow a normal distribution, suited to roughly normal weights. QLoRA: LoRA on top of a 4-bit frozen base, with de-quantisation for compute.

The structure

AAAWgmp1bWIAAAAeanVtZGMycGEAEQAQgAAAqgA4m3EDYzJwYQAAABZcanVtYgAAAEdqdW1kYzJtYQARABCAAACqADibcQN1cm46YzJwYTpmNGNmMTljNi0yNzA4LTQ2NDQtOGNkMS00NWEyYWNmMDkwOGYAAAADl2p1bWIAAAApanVtZGMyYXMAEQAQgAAAqgA4m3EDYzJwYS5hc3NlcnRpb25zAAAAALxqdW1iAAAARGp1bWRjYm9yABEAEIAAAKoAOJtxE2MycGEuaW5ncmVkaWVudC52MwAAAAAYYzJzaFEdDn23i/IHA0SWnMK41YEAAABwY2JvcqNpZGM6Zm9ybWF0bWltYWdlL3N2Zyt4bWxqaW5zdGFuY2VJRHgseG1wOmlpZDpjMWEwNDZiMi0yMDA0LTRkOGItOTc4ZS04MmQ4MGE5MDFkZmFscmVsYXRpb25zaGlwaHBhcmVudE9mAAAB4mp1bWIAAABBanVtZGNib3IAEQAQgAAAqgA4m3ETYzJwYS5hY3Rpb25zLnYyAAAAABhjMnNoh4/TSk+9oK4zzZpXieewqQAAAZljYm9yomdhY3Rpb25zgqJmYWN0aW9ua2MycGEub3BlbmVkanBhcmFtZXRlcnOha2luZ3JlZGllbnRzgaJjdXJseC1zZWxmI2p1bWJmPWMycGEuYXNzZXJ0aW9ucy9jMnBhLmluZ3JlZGllbnQudjNkaGFzaFggMo1wkWu9rGVENL1eteiMJL9pCfZCkPv3DWq4FEr/57WkZmFjdGlvbngdY29tLmFudGhyb3BpYy5jbGF1ZGUucHJvdmlkZWRqcGFyYW1ldGVyc6F4H2NvbS5hbnRocm9waWMub3JpZ2luLWNvbmZpZGVuY2VndW5rbm93bmtkZXNjcmlwdGlvbnhmQ2xhdWRlIHByb3ZpZGVkIHRoaXMgZmlsZSBhdCB0aGUgcmVxdWVzdCBvZiBhIHVzZXIgYW5kIG1heSBoYXZlIGNyZWF0ZWQgb3IgbW9kaWZpZWQgdGhlIGZpbGUgY29udGVudHMubXNvZnR3YXJlQWdlbnShZG5hbWVmQ2xhdWRlcmFsbEFjdGlvbnNJbmNsdWRlZPUAAADIanVtYgAAAEBqdW1kY2JvcgARABCAAACqADibcRNjMnBhLmhhc2guZGF0YQAAAAAYYzJzaClSFh7TpQhZh2DERmSQx/kAAACAY2JvcqVjYWxnZnNoYTI1NmNwYWRNAAAAAAAAAAAAAAAAAGRoYXNoWCBOQ7ayX+DP9qQz+35OzYTpUZxB4pNpvvYwAPqvlzx3ImRuYW1lbmp1bWJmIG1hbmlmZXN0amV4Y2x1c2lvbnOBomVzdGFydBiaZmxlbmd0aBkeBAAAAj5qdW1iAAAAJ2p1bWRjMmNsABEAEIAAAKoAOJtxA2MycGEuY2xhaW0udjIAAAACD2Nib3KlY2FsZ2ZzaGEyNTZpc2lnbmF0dXJleE1zZWxmI2p1bWJmPS9jMnBhL3VybjpjMnBhOmY0Y2YxOWM2LTI3MDgtNDY0NC04Y2QxLTQ1YTJhY2YwOTA4Zi9jMnBhLnNpZ25hdHVyZWppbnN0YW5jZUlEeCx4bXA6aWlkOmY1NzZiOWVkLWEzMmUtNDlhMi1iMzc4LTFmNTJhZjU2ZTI5OHJjcmVhdGVkX2Fzc2VydGlvbnODomN1cmx4LXNlbGYjanVtYmY9YzJwYS5hc3NlcnRpb25zL2MycGEuaW5ncmVkaWVudC52M2RoYXNoWCAyjXCRa72sZUQ0vV616Iwkv2kJ9kKQ+/cNargUSv/ntaJjdXJseCpzZWxmI2p1bWJmPWMycGEuYXNzZXJ0aW9ucy9jMnBhLmFjdGlvbnMudjJkaGFzaFggbWz8IYZlHOgKTkXt7bHBrZqsfWXfmwlY16k6+Put9c2iY3VybHgpc2VsZiNqdW1iZj1jMnBhLmFzc2VydGlvbnMvYzJwYS5oYXNoLmRhdGFkaGFzaFgghXT///71R7qA2oRNWWKE4nygSOIyacWWIwg7sXB4GPx0Y2xhaW1fZ2VuZXJhdG9yX2luZm+jZG5hbWVvQW50aHJvcGljIEZpbGVzZ3ZlcnNpb25lMS4wLjBrc3BlY1ZlcnNpb25lMi40LjAAABA4anVtYgAAAChqdW1kYzJjcwARABCAAACqADibcQNjMnBhLnNpZ25hdHVyZQAAABAIY2JvctKEWQISogEmGCFZAgowggIGMIIBjaADAgECAhRA5aAK7sI50L64g/oGQgU9Z1UTADAKBggqhkjOPQQDAzBJMRcwFQYDVQQKEw5BbnRocm9waWMsIFBCQzEuMCwGA1UEAxMlQW50aHJvcGljIENvbnRlbnQgQ3JlZGVudGlhbHMgUm9vdCBDQTAeFw0yNjA4MDcxODQzNTZaFw0yODA4MDYxOTQzNTZaMEQxFzAVBgNVBAoTDkFudGhyb3BpYywgUEJDMSkwJwYDVQQDEyBBbnRocm9waWMgQ2xhdWRlIENvbnRlbnQgU2lnbmluZzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJh6CmvLUBgFFNU0vUKlOVtE6djd17L5SuwX0LemFisBM3dkd/3cyjxFA3Qo5S46fX0/ihY0VZ7mfb9KF703t5OjWDBWMA4GA1UdDwEB/wQEAwIHgDAVBgNVHSUEDjAMBgorBgEEAYPoXgIBMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUzlHiBIFOZFsj+OPEz5o+nMHXXMIwCgYIKoZIzj0EAwMDZwAwZAIwMXMdFJ4BetLLVY7ORuE9noqbbAZOZn/aArXyTwFAZfKrPzxF2vPoJNf1+UCdg1XGAjBwX1zd9WGqYkqmL5SFqw1QySjr1zJfpJM9+1rdDwSPLMOPOjKuiXjoU/pUUeG9RwmhY3BhZFkNngAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPZYQC7yaQJyyunSQpQNCCknH/lE3sRsGSe2t5nyGvKIauxB33u5WloH31xCtjw2m3ksGOmFbBI2xa0pTQ8q8b4455I=LoRA: W stays frozen, only A and B train; test error by rank (toy net)W (64 x 64), frozen4,096 weights+B64 x rA r x 64W' = W + (alpha / r) B AB starts at 0, so training begins from the base modelTest error (normalised MSE; lower is better), learning rate picked on validation dataneeded change has rank 4 (untuned 0.238)full W20.0061LoRA r=10.0273LoRA r=20.0121LoRA r=40.0003LoRA r=80.0009LoRA r=160.0016LoRA r=320.0027LoRA r=640.0032needed change is full rank (64) (untuned 0.158)full W20.0048LoRA r=10.0767LoRA r=20.0368LoRA r=40.0135LoRA r=80.0112LoRA r=160.0069LoRA r=320.0059LoRA r=640.0057Too small a rank underfits; a rank that matches the change is enough; extra rank adds no gain here. When the change is full rank, LoRA needs a high rank to match full tuning.Toy only: the 'needed change' is low-rank by construction, which is the assumption LoRA relies on.
LoRA structure and test error by rank for a low-rank and a full-rank needed change.

Results

Test error (normalised MSE) Params Needed change rank 4 Needed change full rank
Untuned base 0 0.2378 0.1581
Full tuning of W2 4,096 0.0061 0.0048
Full tuning of all layers 5,376 0.0102 0.0086
LoRA r=1 128 0.0273 0.0767
LoRA r=2 256 0.0121 0.0368
LoRA r=4 512 0.0003 0.0135
LoRA r=8 1,024 0.0009 0.0112
LoRA r=16 2,048 0.0016 0.0069
LoRA r=32 4,096 0.0027 0.0059
LoRA r=64 8,192 0.0032 0.0057
Validation error, rank 8 lr 0.001 lr 0.003 lr 0.01 lr 0.03 lr 0.1
scale alpha/r = 0.25 0.0118 0.0049 0.0015 0.0005 0.0005
scale = 1 0.0067 0.0024 0.0011 0.0008 0.0013
scale = 4 0.0074 0.0033 0.0014 0.0023 0.633
Round-trip error / weight spread Uniform 16 levels Normal-quantile 16 levels Bits per weight
Block 16 0.080 0.081 5.00
Block 64 0.101 0.092 4.25
Block 256 0.118 0.098 4.06
Block 4096 0.147 0.109 4.00
Whole matrix 0.182 0.126 4.00
Toy QLoRA (rank-4 change, LoRA r=8) Test error
16-bit base, untuned 0.2378
Uniform 4-bit, untuned 0.2639
Normal-quantile 4-bit, untuned 0.2541
16-bit base + LoRA 0.0009
Uniform 4-bit + LoRA 0.0088
Normal-quantile 4-bit + LoRA 0.0069
AAAWgmp1bWIAAAAeanVtZGMycGEAEQAQgAAAqgA4m3EDYzJwYQAAABZcanVtYgAAAEdqdW1kYzJtYQARABCAAACqADibcQN1cm46YzJwYTo3OTkzMjFhMC0yMTI2LTQ3NmEtOWIzOS02M2VjMDJkNTllYzEAAAADl2p1bWIAAAApanVtZGMyYXMAEQAQgAAAqgA4m3EDYzJwYS5hc3NlcnRpb25zAAAAALxqdW1iAAAARGp1bWRjYm9yABEAEIAAAKoAOJtxE2MycGEuaW5ncmVkaWVudC52MwAAAAAYYzJzaFlTF34Tw/HVQOghsFs6LiYAAABwY2JvcqNpZGM6Zm9ybWF0bWltYWdlL3N2Zyt4bWxqaW5zdGFuY2VJRHgseG1wOmlpZDowNWU3YjBmNi01NDZmLTQzYTYtYjI2OC03Y2RjZWEzOTA3NGJscmVsYXRpb25zaGlwaHBhcmVudE9mAAAB4mp1bWIAAABBanVtZGNib3IAEQAQgAAAqgA4m3ETYzJwYS5hY3Rpb25zLnYyAAAAABhjMnNoiWSjVVAjKvjyKm7uPAcE4wAAAZljYm9yomdhY3Rpb25zgqJmYWN0aW9ua2MycGEub3BlbmVkanBhcmFtZXRlcnOha2luZ3JlZGllbnRzgaJjdXJseC1zZWxmI2p1bWJmPWMycGEuYXNzZXJ0aW9ucy9jMnBhLmluZ3JlZGllbnQudjNkaGFzaFggTllcphmsM9QMKtripepksX5o2fznLK6MPZOJHCO874mkZmFjdGlvbngdY29tLmFudGhyb3BpYy5jbGF1ZGUucHJvdmlkZWRqcGFyYW1ldGVyc6F4H2NvbS5hbnRocm9waWMub3JpZ2luLWNvbmZpZGVuY2VndW5rbm93bmtkZXNjcmlwdGlvbnhmQ2xhdWRlIHByb3ZpZGVkIHRoaXMgZmlsZSBhdCB0aGUgcmVxdWVzdCBvZiBhIHVzZXIgYW5kIG1heSBoYXZlIGNyZWF0ZWQgb3IgbW9kaWZpZWQgdGhlIGZpbGUgY29udGVudHMubXNvZnR3YXJlQWdlbnShZG5hbWVmQ2xhdWRlcmFsbEFjdGlvbnNJbmNsdWRlZPUAAADIanVtYgAAAEBqdW1kY2JvcgARABCAAACqADibcRNjMnBhLmhhc2guZGF0YQAAAAAYYzJzaLnW7iqCJKTAQmzHMtao8MUAAACAY2JvcqVjYWxnZnNoYTI1NmNwYWRNAAAAAAAAAAAAAAAAAGRoYXNoWCA2rECdmE9v089MqaLt3KpNkB7hLd3ZHThROo1gG3v9smRuYW1lbmp1bWJmIG1hbmlmZXN0amV4Y2x1c2lvbnOBomVzdGFydBibZmxlbmd0aBkeBAAAAj5qdW1iAAAAJ2p1bWRjMmNsABEAEIAAAKoAOJtxA2MycGEuY2xhaW0udjIAAAACD2Nib3KlY2FsZ2ZzaGEyNTZpc2lnbmF0dXJleE1zZWxmI2p1bWJmPS9jMnBhL3VybjpjMnBhOjc5OTMyMWEwLTIxMjYtNDc2YS05YjM5LTYzZWMwMmQ1OWVjMS9jMnBhLnNpZ25hdHVyZWppbnN0YW5jZUlEeCx4bXA6aWlkOmI4OWQyM2ViLWY0MTAtNDg5OC1iYTRiLTQ2YTk0ZjkzMjk1OXJjcmVhdGVkX2Fzc2VydGlvbnODomN1cmx4LXNlbGYjanVtYmY9YzJwYS5hc3NlcnRpb25zL2MycGEuaW5ncmVkaWVudC52M2RoYXNoWCBOWVymGawz1Awq2uKl6mSxfmjZ/Ocsrow9k4kcI7zviaJjdXJseCpzZWxmI2p1bWJmPWMycGEuYXNzZXJ0aW9ucy9jMnBhLmFjdGlvbnMudjJkaGFzaFggeR+leL1vY1pY6HLJbeNE0jzgKk6vK3NO96XtA/vEn2GiY3VybHgpc2VsZiNqdW1iZj1jMnBhLmFzc2VydGlvbnMvYzJwYS5oYXNoLmRhdGFkaGFzaFggxKTAAIrma6IZYgmCZWuUYb1Ol2ELoYk4EOGW/QBXS950Y2xhaW1fZ2VuZXJhdG9yX2luZm+jZG5hbWVvQW50aHJvcGljIEZpbGVzZ3ZlcnNpb25lMS4wLjBrc3BlY1ZlcnNpb25lMi40LjAAABA4anVtYgAAAChqdW1kYzJjcwARABCAAACqADibcQNjMnBhLnNpZ25hdHVyZQAAABAIY2JvctKEWQISogEmGCFZAgowggIGMIIBjaADAgECAhRA5aAK7sI50L64g/oGQgU9Z1UTADAKBggqhkjOPQQDAzBJMRcwFQYDVQQKEw5BbnRocm9waWMsIFBCQzEuMCwGA1UEAxMlQW50aHJvcGljIENvbnRlbnQgQ3JlZGVudGlhbHMgUm9vdCBDQTAeFw0yNjA4MDcxODQzNTZaFw0yODA4MDYxOTQzNTZaMEQxFzAVBgNVBAoTDkFudGhyb3BpYywgUEJDMSkwJwYDVQQDEyBBbnRocm9waWMgQ2xhdWRlIENvbnRlbnQgU2lnbmluZzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJh6CmvLUBgFFNU0vUKlOVtE6djd17L5SuwX0LemFisBM3dkd/3cyjxFA3Qo5S46fX0/ihY0VZ7mfb9KF703t5OjWDBWMA4GA1UdDwEB/wQEAwIHgDAVBgNVHSUEDjAMBgorBgEEAYPoXgIBMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUzlHiBIFOZFsj+OPEz5o+nMHXXMIwCgYIKoZIzj0EAwMDZwAwZAIwMXMdFJ4BetLLVY7ORuE9noqbbAZOZn/aArXyTwFAZfKrPzxF2vPoJNf1+UCdg1XGAjBwX1zd9WGqYkqmL5SFqw1QySjr1zJfpJM9+1rdDwSPLMOPOjKuiXjoU/pUUeG9RwmhY3BhZFkNngAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPZYQJudUoJWaRj+2PsYnpdJ7DwzyscTUso8rs6fGpI+IjNTxIVjjJxxtypwGjYbAGojNdeBrHG8xrYKh1SO4+BITsc=QLoRA idea: 4-bit frozen base plus LoRA; alpha/r against learning rateWeight round-trip error relative to weight spread, normal weights, by block sizeuniform 16 levelsnormal-quantile 16 levels (my NF4-like)bits per weightblock 160.0800.0815.00block 640.1010.0924.25block 2560.1180.0984.06block 40960.1470.1094.00whole matrix0.1820.1264.00Toy QLoRA: all frozen layers quantised to 4 bits (block 64), LoRA r=8 on W2 (test normalised MSE)base, 16-bit, untuned0.2378uniform 4-bit, untuned0.2639normal-quantile 4-bit, untuned0.254116-bit + LoRA0.0009uniform 4-bit + LoRA0.0088normal-quantile 4-bit + LoRA0.0069Validation error, rank 8: scale alpha/r (rows) against learning rate (columns). Best learning rate shifts as the scale grows.lr 0.001lr 0.003lr 0.01lr 0.03lr 0.1scale 0.250.01180.00490.00150.00050.0005scale 1.00.00670.00240.00110.00080.0013scale 4.00.00740.00330.00140.00230.6330
Blockwise 4-bit error, toy QLoRA results, and alpha/r against learning rate.
  1. Rank must cover the change. Below the needed rank the adapter underfits; above it adds nothing here.
  2. LoRA trades capacity for data efficiency; it can trail full tuning when the needed change is high-rank.
  3. Scale and learning rate interact; tune them together.
  4. The base dominates memory, so quantising the base matters more than shrinking the adapter.

Design rules

  • Start with rank 8 to 16 on all attention matrices (add MLP matrices if quality is short) and sweep rank on a validation set.
  • Initialise B to zero and A small random, so training starts at the base model.
  • Tune alpha and the learning rate together; keep alpha : r within a sensible band and watch for divergence.
  • Merge for one model; keep adapters separate for multi-tenant or multi-task serving.
  • Version adapters with the base model, since an adapter is only valid for the exact base weights it was trained on.
  • Use 4-bit bases (QLoRA) when memory is the limit, and compare against a 16-bit run on your own eval.
  • Smaller quantisation blocks cost extra bits; measure error against memory.
  • Hold out data from a later period to check the adapter does not overfit.
  • Run a regression eval on tasks the adapter should not change.
  • Recompute any parameter count you copy (tables sometimes label the matrices wrongly).

Interview questions, with the follow-ups

What are LoRA's rank and alpha, and how do you choose them?

"Rank r is the inner dimension of the low-rank update B A, so it sets the adapter's capacity and size. alpha scales the update by alpha over r. I start at rank 8 to 16 on the attention matrices, sweep rank on validation data (in my toy the matching rank won and extra rank added nothing), and tune alpha together with the learning rate because they trade off; one of my runs diverged at scale 4 with lr 0.1." Follow-up: "What if the task needs a big change to the model?" Rank may need to be high, or full finetuning may be better; in my full-rank toy LoRA needed r of 32 or more to match.

Why initialise B to zero?

"So the adapter starts as an identity change: the model equals the base model at step 0 and training moves away from a known good point. With a random B my toy began at error 0.344 instead of 0.238." Follow-up: "Why not both zero?" Then the gradients to both A and B are zero, so nothing would train; A is random and B is zero.

How do you serve many LoRA-tuned models?

"Keep one frozen base and swap adapters, which saves storage: for 100 customers and a 4096 x 4096 matrix at r=8 it is about 23 million parameters instead of 1.68 billion with merged copies. The cost is a little extra compute per token, which can be reduced with batched adapter kernels. For a single model I merge." Follow-up: "What can go wrong?" An adapter loaded on the wrong base version, or noisy-neighbour load on a shared base.

What does QLoRA change?

"It stores the frozen base in 4 bits with blockwise scales and de-quantises to 16-bit for compute, so a much larger model fits on one GPU; LoRA trains on top. The cost is quantisation error; in my toy LoRA on a 4-bit base reached 0.007 to 0.009 against 0.0009 for 16-bit, and the paper reports parity on its benchmarks, so I would check on my own eval." Follow-up: "Where does the memory go?" Mostly the base weights, activations and optimiser state for the adapter; the adapter itself is tiny.

Common mistakes

  • Raising rank hoping for better quality without a validation curve.
  • Applying LoRA to a single matrix without testing more.
  • Random B initialisation and a worse starting point.
  • Changing alpha without re-tuning the learning rate.
  • Mixing adapters and base versions.
  • Assuming 4-bit is free; it costs accuracy that you must measure.
  • Training on 200 examples with full finetuning and calling LoRA "better" (small data favours small adapters).
  • Copying parameter counts without recomputing (Table 7-6 caption).
  • Ignoring regression tests on tasks the base model did well.
  • Treating a toy result as evidence about LLMs.

What the example does not do

  • No real model: a 64-unit network, random base, and a target built by a low-rank change.
  • The low-rank assumption is built in, so the rank-4 result is flattering by design; the full-rank case is the fairer stress test.
  • Small data: 256 examples make full tuning overfit; with more data the gap may flip.
  • One seed per configuration, with learning rates chosen from a small grid, so small differences (for example between rank 8 and 16) are not conclusive.
  • My quantiser is an approximation (symmetric normal-quantile levels, no double quantisation, no paged optimiser).
  • No attention, no real training dynamics, no mixed precision.
  • Optional real experiment (I did not run this): with a small open model, train LoRA at ranks 4, 8, 16, 32 on one agent step with PyTorch and PEFT, plot validation quality against rank, then repeat with a 4-bit base and compare quality and memory.

Check yourself

Why is B initialised to zero in LoRA? (So the adapter adds nothing at step 0 and training starts exactly from the base model. With a random B my toy started at error 0.344 instead of 0.238.)

For the curious Rank, alpha and learning rate interact

In my toy the needed change was rank 4 by construction, so r=4 won (0.0003) and r=1 underfit (0.0273). Raising r to 64 did not help. When the needed change was full rank, LoRA needed a high rank to match full tuning. At scale alpha/r = 4, lr 0.1 diverged while 0.01 worked, so alpha and learning rate are not independent. All of this is a small NumPy network, not a language model.

What you will use daily at work

Practice What it looks like
Pick rank by the validation curve Start small (4 to 16), raise it only if validation error keeps falling.
Apply LoRA to all attention matrices, often the MLP too Check what your library targets by default.
Merge for one model, or keep adapters separate Separate adapters let one base serve many tenants.
Use QLoRA when memory is the limit A 4-bit frozen base cuts memory about 3.8 times; compare quality with 16-bit.

Draft: confirm the current options in the tuning library you use (target modules, rank, quantisation) and your GPU memory.

What you must be able to say (one page)

  • LoRA in one line. For a frozen weight matrix W, learn two small matrices B (n x r) and A (r x m) and use W' = W + (alpha / r) B A. Only A and B train; r is the rank. In my code B starts at zero, so training starts exactly from the base model.
  • Why it is cheap. A 64 x 64 matrix has 4,096 weights; at rank 4 the adapter has 512 (2 x 64 x 4). A 9 x 9 matrix (81 weights) factors into 9 x 1 and 1 x 9 (18 weights). For GPT-3 the LoRA paper reports about 4.7M trainable parameters, which I recomputed as 0.0027 percent of 175B.
  • Why it can work. The assumption is that the change a task needs is low-rank. In my toy I made the needed change exactly rank 4 by construction, so this is an assumption I built in, not evidence about real models.
  • Rank sweep, my toy (3-layer net, 64 hidden units, 256 training examples, normalised test MSE where 1 means "predict the mean", learning rate chosen on validation data). Needed change is rank 4 (untuned error 0.238): full tuning of that matrix 0.0061 (4,096 parameters), LoRA r=1: 0.0273, r=2: 0.0121, r=4: 0.0003, r=8: 0.0009, r=16: 0.0016, r=32: 0.0027, r=64: 0.0032. A rank below the true one underfits; the matching rank wins; more rank did not help and slightly hurt here, so raising r does not necessarily improve results and may overfit. LoRA beat full tuning because 256 examples cannot pin down 4,096 free weights (full tuning reached 0.0001 train error but 0.0061 test error). That is a statement about my small data, not a general law.
  • When the needed change is full rank (untuned 0.158): full tuning 0.0048, LoRA r=1: 0.0767, 2: 0.0368, 4: 0.0135, 8: 0.0112, 16: 0.0069, 32: 0.0059, 64: 0.0057. LoRA needs a high rank to match full tuning. This is the usual catch: LoRA can trail full finetuning when the needed change is large.
  • Which matrices and what rank in practice. In the LoRA paper's GPT-3 experiment with an 18M-parameter budget, spreading rank 2 over all four attention matrices did best (WikiSQL 70.4, 70.0, 73.0 and 73.2 percent for single matrices at rank 8; MultiNLI 91.0, 90.8, 91.0 and 91.3 percent). I am quoting these from memory and did not re-check the paper. A small r between 4 and 64 is often enough; one practitioner (Raschka) reported r=256 best on his tasks. Adding feed-forward matrices often helps.
  • alpha. The update is scaled by alpha / r; common practitioner advice is to keep alpha : r between 1:8 and 8:1. In my toy at rank 8, the best learning rate moves with the scale: scale 0.25 was best at lr 0.03 to 0.1 (validation error 0.0005), scale 1 at lr 0.03 (0.0008), scale 4 at lr 0.01 (0.0014) and diverged at lr 0.1 (0.633). So alpha and learning rate are not independent; tune one with the other fixed.
  • Why B starts at zero. With B = 0 the adapter adds nothing at step 0 (my test checks the matrix is unchanged). With a random B my toy started at error 0.344 instead of 0.238, so training had to undo a random perturbation first.
  • Merging and serving. Merge B A into W for a single model (no extra latency), or keep adapters separate to serve many fine-tunes from one base. In my test the merged and unmerged outputs agree to 1.2e-15. Example: 100 customers, 4096 x 4096 matrix, r=8: merged copies need 1.68B parameters, one base plus 100 adapters 23.3M. I recomputed 1,677,721,600 and 23,330,816.
  • QLoRA: store the frozen base in 4-bit NF4 (normal-distribution-shaped levels), de-quantise to 16-bit for compute, train LoRA on top, with paged optimisers. The QLoRA authors report finetuning a 65B model on a single 48 GB GPU, and their Guanaco models came close to ChatGPT on a GPT-4-judged benchmark (from memory; not re-checked).
  • My 4-bit experiment (approximate: my level table is a symmetric normal-quantile table, not the real NF4). Round-trip error relative to the weight spread, normal weights: block 16: 0.080 uniform vs 0.081 normal-quantile; block 64: 0.101 vs 0.092; block 256: 0.118 vs 0.098; one block for the whole matrix: 0.182 vs 0.126, at 5.00, 4.25, 4.06 and 4.00 bits per weight (including a 16-bit scale per block). Smaller blocks cut error but cost bits; the normal-quantile table helps most when blocks are large, and at block 16 it did not help.
  • LoRA on a 4-bit base in my toy (all frozen layers quantised at block 64, LoRA r=8): untuned error rose from 0.238 to 0.264 (uniform) and 0.254 (normal-quantile); after LoRA 0.0088 and 0.0069 against 0.0009 for 16-bit LoRA. So LoRA recovers almost all of the task but not all of the quantisation damage in my toy; the QLoRA authors report parity with 16-bit on their benchmarks, which I did not test.
  • Memory is mostly the base, not the adapter. Llama 2 13B weights take 26 GB (13B x 2 bytes) against a 6.55 MB adapter (3.28M parameters x 2 bytes). Cutting adapter parameters barely changes total memory; quantising the base does (16 to about 4.25 bits per weight, about 3.8 times less in my arithmetic).
  • Recount parameters yourself. Rank 2 on all four attention matrices gives 3,276,800 for Llama 2 13B (d=5120, 40 layers) and 18,874,368 for GPT-3 (d=12288, 96 layers); on only two matrices it is 1,638,400 and 9,437,184. Published tables sometimes mix up which matrices they count, so check any figure against the formula before you copy it.
  • What to say in an interview: "LoRA freezes W and learns a low-rank update B A scaled by alpha over r, with B initialised to zero. It trains a tiny fraction of the parameters, can be merged for no latency or kept separate to serve many adapters on one base, and QLoRA adds a 4-bit frozen base to cut memory. I pick rank by the validation curve, usually 8 to 64, apply it to all attention (and often MLP) matrices, and expect it to trail full tuning on hard shifts."
  • Honest limits: a tiny NumPy network with a built-in low-rank target; the quantiser is my approximation; no real language model was tuned.