llm.core — Building Blocks¶
Reusable, framework-agnostic building blocks shared by training and serving. Everything here is pure PyTorch (no FastAPI, no trainer plumbing) so it can be reused in notebooks and other runners.
KV Cache¶
kv_cache
¶
KV Cache manager for efficient autoregressive generation.
This module provides a pre-allocated cache that avoids repeated memory allocations during token generation, significantly improving inference performance.
KVCache
¶
Pre-allocated Key-Value cache for efficient autoregressive generation.
Instead of using torch.cat to concatenate new K/V with past K/V (which allocates new memory each step), this class pre-allocates buffers and updates them in-place.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
max_batch_size
|
int
|
Maximum batch size to support. |
必需 |
max_seq_len
|
int
|
Maximum sequence length to cache. |
必需 |
num_kv_heads
|
int
|
Number of key-value heads (for GQA, this may differ from num_heads). |
必需 |
head_dim
|
int
|
Dimension of each attention head. |
必需 |
device
|
device | str | None
|
Device to allocate buffers on. |
None
|
dtype
|
dtype | None
|
Data type for cache buffers. |
None
|
Example
cache = KVCache(max_batch_size=2, max_seq_len=16, num_kv_heads=4, head_dim=64, ... device="cpu", dtype=torch.float32) k_new = torch.randn(2, 4, 8, 64) # (batch, kv_heads, seq, head_dim) v_new = torch.randn(2, 4, 8, 64) _ = cache.update(k_new, v_new) # returns (k_cache, v_cache) views
源代码位于: src/llm/core/kv_cache.py
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 | |
update
¶
Update cache with new key-value tensors and return full cache view.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
k_new
|
Tensor
|
New key tensor of shape [B, N_kv, S_new, D]. |
必需 |
v_new
|
Tensor
|
New value tensor of shape [B, N_kv, S_new, D]. |
必需 |
返回:
| 类型 | 描述 |
|---|---|
Tensor
|
Tuple of (k_cached, v_cached) containing all cached keys and values |
Tensor
|
up to and including the new tokens. Shape: [B, N_kv, S_total, D]. |
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
If update would exceed max_seq_len. |
源代码位于: src/llm/core/kv_cache.py
update_at_indices
¶
Update cache at specific batch indices and positions.
This is used for continuous batching or when batch slots are managed explicitly.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
batch_indices
|
Tensor
|
Tensor of shape [B_curr] containing the cache slot indices. |
必需 |
k_new
|
Tensor
|
New key tensor of shape [B_curr, N_kv, S_new, D]. |
必需 |
v_new
|
Tensor
|
New value tensor of shape [B_curr, N_kv, S_new, D]. |
必需 |
start_pos
|
Tensor | int
|
Starting position to write to. Can be an int (broadcast) or
Tensor of shape |
必需 |
返回:
| 名称 | 类型 | 描述 |
|---|---|---|
Tensor
|
Tuple of (k_out, v_out) for the current batch. |
|
Note |
Tensor
|
This returns the full valid context for the current batch indices. |
Shape |
tuple[Tensor, Tensor]
|
[B_curr, N_kv, Max_Context_Len, D]. |
tuple[Tensor, Tensor]
|
Since different sequences have different lengths, we return up to max(start_pos + S_new). |
|
tuple[Tensor, Tensor]
|
Correct handling usually implies the model knows how to mask using attention mask. |
源代码位于: src/llm/core/kv_cache.py
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | |
reset
¶
get_usable_length
¶
from_model_config
classmethod
¶
from_model_config(max_batch_size, max_seq_len, num_layers, num_kv_heads, head_dim, device=None, dtype=None)
Create a list of KVCache objects, one per transformer layer.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
max_batch_size
|
int
|
Maximum batch size. |
必需 |
max_seq_len
|
int
|
Maximum sequence length. |
必需 |
num_layers
|
int
|
Number of transformer layers. |
必需 |
num_kv_heads
|
int
|
Number of KV heads per layer. |
必需 |
head_dim
|
int
|
Dimension per head. |
必需 |
device
|
device | str | None
|
Target device. |
None
|
dtype
|
dtype | None
|
Data type. |
None
|
返回:
| 类型 | 描述 |
|---|---|
list[KVCache]
|
List of KVCache objects, one for each layer. |
源代码位于: src/llm/core/kv_cache.py
create_decoder_kv_caches
¶
Create per-layer KV caches sized for a DecoderModel.
源代码位于: src/llm/core/kv_cache.py
Attention Implementations¶
mha
¶
MultiHeadAttention
¶
Bases: Module
源代码位于: src/llm/core/attn/mha.py
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 | |
forward
¶
forward(hidden_states, attn_mask=None, is_causal=None, kv_cache=None, use_cache=False, batch_indices=None, start_pos=None, paged_kv_cache=None, layer_idx=None, prefix_kv=None)
Forward pass.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
hidden_states
|
Tensor
|
Input tensor of shape [B, S, H] (Batch, Sequence Length, Hidden Size). |
必需 |
attn_mask
|
Tensor | None
|
Optional attention mask.
- For F.scaled_dot_product_attention, expected to be a boolean tensor where |
None
|
is_causal
|
bool | None
|
Whether to enforce causal masking for this forward pass.
- If |
None
|
kv_cache
|
KVCache | None
|
Pre-allocated KV cache for efficient autoregressive generation. When provided, updates are done in-place without memory allocation. |
None
|
prefix_kv
|
tuple[Tensor, Tensor] | None
|
Optional prefix K/V to prepend to the
projected K/V before the attention compute. Used by the Prefix Tuning slice
(T2 PEFT) — see :class: |
None
|
use_cache
|
bool
|
Whether to return the updated (key, value) pair. |
False
|
batch_indices
|
Tensor | None
|
Indices for specific KV cache slots [B]. Use with update_at_indices. |
None
|
start_pos
|
int | Tensor | None
|
Explicit write position for cache update. required if batch_indices is used. |
None
|
paged_kv_cache
|
PagedKVCache | None
|
Block-allocator KV cache. When set
the linear |
None
|
layer_idx
|
int | None
|
Index of this block in the decoder. Required
when |
None
|
返回:
| 类型 | 描述 |
|---|---|
Tensor | tuple[Tensor, tuple[Tensor, Tensor]]
|
Tensor or tuple[Tensor, tuple[Tensor, Tensor]]: - If use_cache=False: Output tensor of shape [B, S, H]. - If use_cache=True: (Output tensor, (current_key, current_value)) |
源代码位于: src/llm/core/attn/mha.py
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 | |
sdpa
¶
sdpa
¶
sdpa(query, key, value, attn_mask=None, attn_bias=None, dropout_p=0.0, is_causal=False, scale=None, window_size=None, prefix_len=0)
Computes Scaled Dot-Product Attention using torch.nn.functional.scaled_dot_product_attention.
Acts as a compatibility wrapper for the codebase conventions:
1. Handles attn_mask where True indicates masking out (opposite to Torch SDPA).
2. Handles window_size by manually merging masks if necessary.
3. Folds a signed additive attn_bias (ALiBi) into the float mask.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
query
|
Tensor
|
Shape (B, N, Sq, D). |
必需 |
key
|
Tensor
|
Shape (B, N, Sk, D). |
必需 |
value
|
Tensor
|
Shape (B, N, Sk, D). |
必需 |
attn_mask
|
Tensor | None
|
Mask where True indicates elements to MASK OUT. Can be boolean or 0/1 float additive (legacy). |
None
|
attn_bias
|
Tensor | None
|
Signed additive score bias (ALiBi), shape broadcastable to [B, N, Sq, Sk]. Summed into the mask (never through the 0/-inf masking channels). |
None
|
dropout_p
|
float
|
Dropout probability. |
0.0
|
is_causal
|
bool
|
Whether to apply causal masking. |
False
|
scale
|
float | None
|
Scaling factor. |
None
|
window_size
|
int | None
|
Sliding window size. |
None
|
prefix_len
|
int
|
How many prefix K/V columns were prepended ahead of the real keys (Prefix Tuning). Shifts any causal diagonal by this amount so the real context stays visible (round-71 fix). |
0
|
源代码位于: src/llm/core/attn/sdpa.py
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | |
mla
¶
MultiLatentAttention
¶
Bases: Module
源代码位于: src/llm/core/attn/mla.py
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 | |
forward
¶
forward(hidden_states, attn_mask=None, is_causal=None, kv_cache=None, use_cache=False, batch_indices=None, start_pos=None, paged_kv_cache=None, layer_idx=None, prefix_kv=None)
Optimized forward pass for the multi-latent attention mechanism.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
hidden_states
|
Tensor
|
Input tensor with shape [batch_size, seq_len, hidden_size]. |
必需 |
attn_mask
|
Tensor | None
|
Optional mask tensor with shape [batch_size, 1, 1, seq_len]. 1 indicates positions to attend to, 0 indicates positions to mask. |
None
|
kv_cache
|
KVCache | None
|
Linear |
None
|
paged_kv_cache
|
PagedKVCache | None
|
Block-allocator |
None
|
layer_idx
|
int | None
|
Required when |
None
|
prefix_kv
|
tuple[Tensor, Tensor] | None
|
Optional |
None
|
返回:
| 类型 | 描述 |
|---|---|
Tensor | tuple[Tensor, None]
|
Output tensor of shape |
Tensor | tuple[Tensor, None]
|
When |
Tensor | tuple[Tensor, None]
|
was updated in-place so there is nothing to return alongside |
Tensor | tuple[Tensor, None]
|
the output (unlike MHA, which exposes the cached K, V). |
源代码位于: src/llm/core/attn/mla.py
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 | |
flash_attn
¶
Flash Attention 2 attention implementation.
Registered as attn_impl="flash_attn" through ATTENTION_REGISTRY.
The flash-attn package is an optional dependency — importing this
module never raises, but instantiating :class:FlashAttention does if
the package is not installed. This mirrors the soft-dependency contract
used elsewhere in the project (e.g. huggingface_hub in
compat.hf_loader).
The class itself follows the same surface as
:class:llm.core.attn.MultiHeadAttention so it can be substituted
transparently: same projection layers, same KV-cache integration, same
output projection. The only difference is the attention kernel:
flash_attn.flash_attn_func instead of
torch.nn.functional.scaled_dot_product_attention.
On supported hardware (Ampere/Hopper) this is meaningfully faster for training and (especially) long-context decode. On other devices the fallback path through PyTorch SDPA in MHA is the right choice.
FlashAttention
¶
Bases: Module
源代码位于: src/llm/core/attn/flash_attn.py
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 | |
forward
¶
forward(hidden_states, attn_mask=None, is_causal=None, kv_cache=None, use_cache=False, batch_indices=None, start_pos=None, paged_kv_cache=None, layer_idx=None, prefix_kv=None)
Forward pass.
See :meth:MultiHeadAttention.forward for the full argument
contract — the signatures are intentionally identical so the
continuous batching engine and training engine can pick
flash_attn as a drop-in replacement.
Note
attn_mask is ignored — flash_attn_func does not
accept arbitrary masks. For non-causal masking or padded
sequences use is_causal=False and pre-pad, or fall back
to attn_impl="mha". Sliding-window on dense inputs is
supported via window_size= (threaded by the decoder,
RIL ISS-242); the still-future piece is combining a sliding
window with a padding mask — that needs
flash_attn_varlen_func (variable-length batches).
paged_kv_cache is also rejected on this path — flash-attn
does not expose a paged-attn kernel; use attn_impl="mha"
when serving with paged KV.
prefix_kv is supported (Li & Liang 2021). The prefix
K/V are concatenated to the projected K/V after the
KV-cache write (so the cache stores only dynamic tokens)
and before the GQA repeat (so the prefix is treated like a
regular token and replicated to all query heads). Prefix
dtype is auto-cast to the projected K/V dtype to satisfy
flash_attn_func's fp16/bf16 requirement. The captured
current_kv (when use_cache=True) excludes the
prefix — matching the MHA contract at
MultiHeadAttention.forward.
源代码位于: src/llm/core/attn/flash_attn.py
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 | |
base
¶
Attention-layer protocols shared by all attn/ implementations.
Defines the optional extension points adapters (e.g. Prefix Tuning)
rely on. Implementations only need to honor the protocols they
genuinely support — anything else raises NotImplementedError at
adapter construction time so the failure mode is loud, not silent.
PrefixCapableAttention
¶
Bases: Protocol
Attention impls that accept an optional prefix_kv to prepend.
The prefix K/V are concatenated to the projected K/V along the sequence dimension before the attention compute and after any KV-cache write — so the cache only holds the dynamically- generated tokens and the prefix is recomputed (or folded to a static buffer) on every forward.
Implementations that don't support prefix tuning (MLA, Flash
Attention fused kernels, etc.) should leave prefix_kv as an
accepted-but-ignored arg or raise NotImplementedError. The
PrefixTuningAttention wrapper guards construction with an
explicit isinstance check so the failure is at adapter build
time, not at first forward.
prefix_kv is a (prefix_k, prefix_v) tuple of shape
[B, num_kv_heads, prefix_len, head_dim], or None to skip
prefix injection (the default).
源代码位于: src/llm/core/attn/base.py
Paged Attention¶
Block-allocator KV cache for serving (see ADR-004):
paged_kv_cache
¶
Paged KV Cache for memory-efficient inference.
PrefixCache
¶
Cache for storing prefix KV blocks (block_ids only).
源代码位于: src/llm/core/paged_attention/paged_kv_cache.py
add
¶
Add prefix blocks to cache.
源代码位于: src/llm/core/paged_attention/paged_kv_cache.py
get
¶
Get cached block IDs for prefix.
remove
¶
Drop a prefix entry (no-op if absent).
Used when the sequence that owned the cached blocks is freed — the stored block IDs become dangling and must not be replayed (RIL ISS-071). Because LRU eviction may already have dropped the entry, absence is not an error.
源代码位于: src/llm/core/paged_attention/paged_kv_cache.py
PagedKVCache
¶
Block-level KV cache for paged attention.
源代码位于: src/llm/core/paged_attention/paged_kv_cache.py
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 | |
add_prefix
¶
Add prefix blocks to cache, owned by seq_id.
A sequence registers at most ONE live prefix entry: :meth:free
drops the entry its owner registered (and only that entry), so a
re-registration under a different hash evicts the previous one here
to keep that bookkeeping exact (RIL TASK-065).
源代码位于: src/llm/core/paged_attention/paged_kv_cache.py
try_get_prefix_blocks
¶
Try to get cached prefix blocks.
源代码位于: src/llm/core/paged_attention/paged_kv_cache.py
stage_prefix
¶
Start a new sequence sharing a cached prefix (prefix replay).
Creates the sequence in the block manager with the cached blocks
forked into its table (shared, refcounted — no K/V is copied). The
sequence is recorded as already owning num_prefix_tokens tokens,
so a subsequent :meth:update appends at the right offset and copies
on write before a token lands inside a still-shared block.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
seq_id
|
int
|
Sequence identifier (slot id on the engine path). |
必需 |
prefix_block_ids
|
list[int]
|
Block ids from :meth: |
必需 |
num_prefix_tokens
|
int
|
Number of already-owned prefix tokens. |
必需 |
返回:
| 类型 | 描述 |
|---|---|
list[int]
|
The staged block table. |
源代码位于: src/llm/core/paged_attention/paged_kv_cache.py
update
¶
Append new tokens to sequence.
For a brand-new sequence this allocates fresh blocks; for an existing sequence it extends the block table only if the new tokens cross a block boundary.
layer_idx scopes the write to a single transformer layer: the
decoder calls :meth:update once per layer with that layer's own K/V,
and each call must write only its own slice of k_cache /
v_cache (which are [num_layers, ...]). Only the layer that
calls first (layer_idx == 0) allocates / extends the block table
and advances the sequence's token count; the remaining layers reuse
the same block table and write at the same token offsets without
re-advancing. (Default 0 keeps the single-layer contract intact.)
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
seq_id
|
int
|
Sequence identifier. |
必需 |
k_new
|
Tensor
|
[batch, tokens, num_kv_heads, head_dim] |
必需 |
v_new
|
Tensor
|
[batch, tokens, num_kv_heads, head_dim] |
必需 |
layer_idx
|
int
|
Which layer's cache slice to write. |
0
|
返回:
| 类型 | 描述 |
|---|---|
list[int]
|
List of physical block IDs allocated for this sequence |
list[int]
|
(initial allocation) or the current full block table |
list[int]
|
(extension). |
源代码位于: src/llm/core/paged_attention/paged_kv_cache.py
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 | |
get_block_table
¶
get
¶
Get KV cache slice for a sequence range.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
seq_id
|
int
|
Sequence identifier. |
必需 |
start_idx
|
int
|
Starting token index (inclusive). |
必需 |
end_idx
|
int
|
Ending token index (exclusive). |
必需 |
layer_idx
|
int
|
Which layer's cache slice to read (default 0 keeps the single-layer contract; multi-layer readers must pass the layer whose KV they're attending over). |
0
|
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
If |
源代码位于: src/llm/core/paged_attention/paged_kv_cache.py
free
¶
Free blocks when sequence completes.
The sequence's OWN prefix-cache entry (the one it registered via
:meth:add_prefix) is dropped BEFORE its blocks are freed: the entry
stores this sequence's physical block IDs, and once
free_sequence returns them to the allocator a later request may
be handed the same blocks. Leaving it in place would replay
another/in-flight sequence's newly-written K/V as a cached prefix —
use-after-free of the KV blocks (RIL ISS-071).
Only the entry the sequence itself registered is removed (via
_seq_to_hash, which :meth:add_prefix keeps exact by evicting a
stale prior entry on re-registration). A sequence that merely
REPLAYED a prefix via :meth:stage_prefix shared the owner's
blocks, which remain live (and pristine — every write into a shared
block copy-on-writes) for as long as the owner holds them, so its
free must not evict an entry it does not own; doing so would make the
first replay destroy the very cache entry that served it (RIL
TASK-065).
源代码位于: src/llm/core/paged_attention/paged_kv_cache.py
attention
¶
Paged Attention forward implementation.
paged_attention_forward
¶
paged_attention_forward(q, k_cache, v_cache, block_tables, seq_lens, num_kv_heads, block_size=16, query_lens=None)
Paged attention forward pass.
Supports both prefill (q with multiple query tokens) and decode
(q with a single query token per sequence). Each row of q
attends to its full cached context (the first seq_lens[b] tokens
of sequence b), regardless of how many query tokens that row
carries. The original Python-fallback kernel gathered the whole k/v
slice per sequence regardless of S_q; the multi-token generalisation
just lets the matmul produce S_q outputs instead of one.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
q
|
Tensor
|
Query tensor [batch, num_heads, query_len, head_dim]. |
必需 |
k_cache
|
Tensor
|
KV cache tensor. Either the per-layer slice
|
必需 |
v_cache
|
Tensor
|
Same shape as |
必需 |
block_tables
|
Tensor
|
[batch, max_blocks] physical block IDs per sequence. |
必需 |
seq_lens
|
Tensor
|
Current sequence lengths [batch]. |
必需 |
num_kv_heads
|
int
|
Number of KV heads. |
必需 |
block_size
|
int
|
Tokens per block. |
16
|
query_lens
|
Tensor | None
|
Optional per-row number of REAL query tokens [batch].
In continuous batching, |
None
|
返回:
| 类型 | 描述 |
|---|---|
Tensor
|
Attention output tensor [batch, num_heads, query_len, head_dim]. |
源代码位于: src/llm/core/paged_attention/attention.py
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | |
block_allocator
¶
Block Allocator for Paged Attention.
Manages allocation and deallocation of physical memory blocks.
BlockAllocator
¶
Allocator for physical memory blocks.
Uses a free-list approach to efficiently manage block allocation and deallocation. Supports reference counting for copy-on-write.
源代码位于: src/llm/core/paged_attention/block_allocator.py
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | |
can_allocate
¶
allocate
¶
Allocate a single block.
返回:
| 类型 | 描述 |
|---|---|
int
|
Block index. |
引发:
| 类型 | 描述 |
|---|---|
RuntimeError
|
If no free blocks are available. |
源代码位于: src/llm/core/paged_attention/block_allocator.py
allocate_n
¶
Allocate multiple blocks.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
n
|
int
|
Number of blocks to allocate. |
必需 |
返回:
| 类型 | 描述 |
|---|---|
list[int]
|
List of block indices. |
引发:
| 类型 | 描述 |
|---|---|
RuntimeError
|
If not enough free blocks are available. |
源代码位于: src/llm/core/paged_attention/block_allocator.py
free
¶
Free a block (decrement reference count).
The block is only returned to the free list when its reference count reaches zero.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
block_id
|
int
|
Block index to free. |
必需 |
源代码位于: src/llm/core/paged_attention/block_allocator.py
free_all
¶
fork
¶
Fork a block for copy-on-write.
Increments the reference count instead of copying.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
block_id
|
int
|
Block to fork. |
必需 |
返回:
| 类型 | 描述 |
|---|---|
int
|
Same block_id (sharing the physical block). |
源代码位于: src/llm/core/paged_attention/block_allocator.py
get_ref_count
¶
is_shared
¶
copy_on_write
¶
Perform copy-on-write if block is shared.
If the block has ref_count > 1, allocates a new block and decrements the old block's ref_count.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
block_id
|
int
|
Block that may need copying. |
必需 |
返回:
| 类型 | 描述 |
|---|---|
int
|
New block_id (may be same if not shared). |
源代码位于: src/llm/core/paged_attention/block_allocator.py
block_manager
¶
Block Manager for Paged Attention.
Manages logical-to-physical block mapping for sequences.
SequenceBlockInfo
dataclass
¶
Block information for a single sequence.
源代码位于: src/llm/core/paged_attention/block_manager.py
BlockManager
¶
Manages block allocation for multiple sequences.
Maintains a mapping from sequence IDs to their block tables, handling allocation, extension, and freeing of blocks.
源代码位于: src/llm/core/paged_attention/block_manager.py
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 | |
can_allocate_sequence
¶
Check if a new sequence with given tokens can be allocated.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
num_tokens
|
int
|
Number of tokens in the sequence. |
必需 |
返回:
| 类型 | 描述 |
|---|---|
bool
|
True if allocation is possible. |
源代码位于: src/llm/core/paged_attention/block_manager.py
allocate_sequence
¶
Allocate blocks for a new sequence.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
seq_id
|
int
|
Unique sequence identifier. |
必需 |
num_tokens
|
int
|
Initial number of tokens. |
必需 |
返回:
| 类型 | 描述 |
|---|---|
list[int]
|
List of physical block IDs for the first layer |
list[int]
|
(all layers get the same logical structure). |
引发:
| 类型 | 描述 |
|---|---|
RuntimeError
|
If allocation fails. |
ValueError
|
If sequence already exists. |
源代码位于: src/llm/core/paged_attention/block_manager.py
extend_sequence
¶
Extend a sequence with additional tokens.
Allocates new blocks if needed.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
seq_id
|
int
|
Sequence to extend. |
必需 |
num_new_tokens
|
int
|
Number of new tokens to add. |
必需 |
返回:
| 类型 | 描述 |
|---|---|
list[int]
|
Updated block table for the sequence. |
源代码位于: src/llm/core/paged_attention/block_manager.py
free_sequence
¶
Free all blocks associated with a sequence.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
seq_id
|
int
|
Sequence to free. |
必需 |
源代码位于: src/llm/core/paged_attention/block_manager.py
fork_sequence
¶
Fork a sequence using copy-on-write.
Creates a new sequence that shares blocks with the source until either is modified.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
src_seq_id
|
int
|
Source sequence to fork from. |
必需 |
dst_seq_id
|
int
|
New sequence ID. |
必需 |
返回:
| 类型 | 描述 |
|---|---|
list[int]
|
Block table for the new sequence. |
源代码位于: src/llm/core/paged_attention/block_manager.py
allocate_sequence_shared_prefix
¶
Create a new sequence whose initial blocks are a SHARED prefix.
Used for paged prefix replay: the cached prefix blocks belong to
another (still-live) sequence, but a new request with the same prompt
may reference them for reads without recomputing their K/V. Each
block table entry is forked (refcount +1 on every layer allocator)
— nothing is copied; the sequence must copy-on-write before any write
lands inside a shared block (:meth:cow_block), or the prefix cache
owner's K/V would be corrupted.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
seq_id
|
int
|
Unique sequence identifier. |
必需 |
prefix_block_ids
|
list[int]
|
Physical block ids (layer 0's view; ids are identical across layers) of the cached prefix. |
必需 |
num_tokens
|
int
|
Number of prefix tokens this sequence already owns (the staged prefix length). |
必需 |
返回:
| 类型 | 描述 |
|---|---|
list[int]
|
The sequence's block table (the shared prefix blocks). |
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
If the sequence already exists, the prefix is empty,
or |
源代码位于: src/llm/core/paged_attention/block_manager.py
is_block_shared
¶
Whether a block is referenced by more than one sequence.
Blocks are forked/freed uniformly across the per-layer allocators, so the layer-0 refcount is authoritative.
源代码位于: src/llm/core/paged_attention/block_manager.py
cow_block
¶
Copy-on-write a logical block across every layer allocator.
Allocates one fresh physical block per layer and decrements the shared block's refcount on each. Because all allocators allocate in lock-step (identical call order), every layer returns the same new id, preserving the cross-layer block-id invariant. The caller must copy the block's data into the new id before writing into it.
返回:
| 类型 | 描述 |
|---|---|
int
|
The new private block id (or |
int
|
shared, in which case nothing is allocated or decremented). |
源代码位于: src/llm/core/paged_attention/block_manager.py
get_block_table
¶
Get the block table for a sequence.
get_num_tokens
¶
Get the number of tokens in a sequence.
get_all_sequence_ids
¶
MLP Variants¶
mlp
¶
MLP
¶
Bases: Module
Multi-Layer Perceptron (MLP).
Transformer-style Feed-Forward Networks with flexible normalization.
Args:
hidden_size (int): Dimensionality of inputs and outputs.
intermediate_size (int, optional): Dimensionality of the inner layer. Defaults to 4 * hidden_size.
activation (str or nn.Module): Activation name or module. Defaults to "gelu".
dropout_p (float): Dropout probability. Defaults to 0.1.
norm_first (bool): Whether to apply normalization before or after (pre-LN vs post-LN). Defaults to True.
norm_type (Type[nn.Module] or nn.Module): Normalization layer type or instance. Defaults to nn.LayerNorm.
norm_eps (float): Epsilon for normalization layers. Defaults to 1e-5.
bias (bool): Whether to include bias terms in Linear layers. Defaults to True.
device (torch.device, optional): Device for parameters. Defaults to None.
dtype (torch.dtype, optional): Dtype for parameters. Defaults to None.
源代码位于: src/llm/core/mlp.py
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | |
forward
¶
Forward pass with optional pre-LayerNorm and residual connection.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
hidden_states
|
Tensor
|
Input tensor of shape [..., hidden_size]. |
必需 |
返回:
| 类型 | 描述 |
|---|---|
Tensor
|
torch.Tensor: Output tensor with same shape as input. |
源代码位于: src/llm/core/mlp.py
moe
¶
MoE
¶
Bases: Module
Mixture of Experts (MoE) Layer.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
hidden_size
|
int
|
The dimensionality of the input and output. |
必需 |
num_experts
|
int
|
The total number of experts. |
必需 |
top_k
|
int
|
The number of top experts to select for each token. |
必需 |
intermediate_size
|
int
|
The intermediate size for each expert's MLP. Defaults to 4 * hidden_size. |
None
|
activation
|
str or Module
|
Activation function for experts. Defaults to "gelu". |
'gelu'
|
dropout_p
|
float
|
Dropout probability for experts. Defaults to 0.1. |
0.1
|
norm_type
|
Type[Module] or Module
|
Normalization layer type for experts. Defaults to nn.LayerNorm. |
LayerNorm
|
norm_eps
|
float
|
Epsilon for normalization layers in experts. Defaults to 1e-5. |
1e-05
|
bias
|
bool
|
Whether to include bias terms in Linear layers of experts. Defaults to True. |
True
|
device
|
device
|
Device for parameters. Defaults to None. |
None
|
dtype
|
dtype
|
Dtype for parameters. Defaults to None. |
None
|
源代码位于: src/llm/core/moe/moe.py
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | |
forward
¶
Forward pass of the MoE layer.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
x
|
Tensor
|
Input tensor of shape [..., hidden_size]. |
必需 |
返回:
| 类型 | 描述 |
|---|---|
Tensor
|
torch.Tensor: Output tensor with same shape as input. |
源代码位于: src/llm/core/moe/moe.py
Transformer Block¶
transformer_block
¶
TransformerBlock
¶
Bases: Module
A single Transformer block, comprising a Multi-Head Attention (MHA) layer and a Multi-Layer Perceptron (MLP) layer, with normalization and residual connections.
The block can be configured for Pre-LN (Layer Normalization before sublayer) or Post-LN (Layer Normalization after sublayer and residual connection).
源代码位于: src/llm/core/transformer_block.py
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | |
forward
¶
forward(hidden_states, attn_mask=None, is_causal=None, kv_cache=None, use_cache=False, batch_indices=None, start_pos=None, paged_kv_cache=None, layer_idx=None)
Forward pass of the Transformer block.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
hidden_states
|
Tensor
|
Input tensor of shape [B, S, H]. |
必需 |
attn_mask
|
Tensor
|
Attention mask for MHA. |
None
|
is_causal
|
bool
|
Overrides the default MHA causality for this pass.
If None, MHA's default |
None
|
kv_cache
|
KVCache | None
|
Pre-allocated KV cache for efficient autoregressive generation. |
None
|
use_cache
|
bool
|
Whether to return the updated (key, value) pair. |
False
|
batch_indices
|
Tensor | None
|
Cache update indices. |
None
|
start_pos
|
int | Tensor | None
|
Cache update position. |
None
|
paged_kv_cache
|
object | None
|
Block-allocator KV cache; ignored
when |
None
|
layer_idx
|
int | None
|
Index of this block in the decoder; required
when |
None
|
返回:
| 类型 | 描述 |
|---|---|
Tensor | tuple[Tensor, tuple[Tensor, Tensor] | None]
|
torch.Tensor or tuple[torch.Tensor, tuple[torch.Tensor, torch.Tensor]]: - If use_cache=False: Output tensor of shape [B, S, H]. - If use_cache=True: (Output tensor, (current_key, current_value)) |
源代码位于: src/llm/core/transformer_block.py
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | |
Normalization Layers¶
rms_norm
¶
RMSNorm
¶
Bases: Module
Root Mean Square Normalization (RMSNorm) 实现.
RMSNorm 是 LayerNorm 的一种简化形式. 它仅使用激活值的均方根统计量进行归一化, 而不进行中心化 (减去均值). 通常只包含一个可学习的缩放参数 (gamma/weight), 不包含可学习的偏置参数 (beta).
参考文献: Zhang, Biao, and Rico Sennrich. "Root mean square layer normalization." Advances in Neural Information Processing Systems 32 (2019). 论文链接: https://arxiv.org/abs/1910.07467
数学公式 (对于特征向量 x): RMS(x) = sqrt( (1/H) * Σ(x_i²) + ε ) (H = 归一化维度的大小) x_normalized = x / RMS(x) output = gamma * x_normalized
参数
normalized_shape (int 或 list/tuple of ints):
需要进行归一化的输入张量的结尾维度形状.
与 LayerNorm 中的定义相同.
eps (float):
加在均方根计算中的小常数, 防止除零错误并提高数值稳定性.
默认为 1e-6 (常见于 RMSNorm 实现).
elementwise_affine (bool):
如果为 True, 则此模块包含可学习的缩放参数 gamma (gamma/weight),
形状与 normalized_shape 相同. gamma 初始化为 1.
注意: RMSNorm 通常不使用偏置项 (beta).
默认为 True.
源代码位于: src/llm/core/rms_norm.py
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | |
forward
¶
前向传播函数
参数
hidden_states: 输入张量, 其尾部维度应与 normalized_shape 匹配.
形状例如: [batch_size, ..., *normalized_shape]
返回
归一化后的张量, 形状与输入 hidden_states 相同.
源代码位于: src/llm/core/rms_norm.py
rms_norm_numpy
¶
RMS Normalization 的 NumPy 实现 (简化版)
注意: 此版本为了简洁, 固定在最后一个轴 (axis=-1) 上进行归一化. 主要用于帮助理解 RMSNorm 的核心计算步骤. 不包含偏置项.
参数
x: 输入 NumPy 数组, 形状例如 [batch_size, ..., feature_dim] gamma: 缩放参数 (如果提供), 形状应为 [feature_dim] eps: 防止除零错误的小常数
返回
归一化后的 NumPy 数组, 形状与输入 x 相同.
源代码位于: src/llm/core/rms_norm.py
layer_norm
¶
LayerNorm
¶
Bases: Module
自定义 Layer Normalization 实现 (更接近 PyTorch 内置版本)
Layer Normalization 通过对单个样本内的特征维度进行归一化来稳定训练过程. 与 Batch Normalization 不同, LayerNorm 对每个样本独立操作, 不依赖于 Batch Size, 因此特别适用于序列模型 (RNN, Transformer).
数学公式 (对于一个样本 x 中的一个元素 x_i): μ = (1/H) * Σ(x_i) (在归一化维度 H 上求均值) σ² = (1/H) * Σ((x_i - μ)²) (在归一化维度 H 上求方差) x_normalized = (x - μ) / sqrt(σ² + ε) output = gamma * x_normalized + beta
参数
normalized_shape (int 或 list/tuple of ints):
需要进行归一化的输入张量的结尾维度形状.
例如, 如果输入形状是 (N, C, H, W) 且希望对最后两个维度 (H, W) 进行归一化,
则 normalized_shape 应为 (H, W) 或 [H, W].
如果只对最后一个维度进行归一化, 可以传入一个整数, 如 W.
eps (float):
加在分母中的小常数, 防止除零错误并提高数值稳定性. 默认为 1e-5.
elementwise_affine (bool):
如果为 True, 则此模块包含可学习的仿射参数 gamma (weight) 和 beta (bias),
形状与 normalized_shape 相同. gamma 初始化为 1, beta 初始化为 0.
默认为 True.
源代码位于: src/llm/core/layer_norm.py
forward
¶
前向传播函数
参数
hidden_states: 输入张量, 其尾部维度应与 normalized_shape 匹配.
例如, 形状可以是 [batch_size, ..., *normalized_shape]
返回
归一化后的张量, 形状与输入 hidden_states 相同.
源代码位于: src/llm/core/layer_norm.py
layer_norm_numpy
¶
Layer Normalization 的 NumPy 实现 (简化版)
注意: 此版本为了简洁, 固定在最后一个轴 (axis=-1) 上进行归一化. 主要用于帮助理解 LayerNorm 的核心计算步骤.
参数
x: 输入 NumPy 数组, 形状例如 [batch_size, ..., feature_dim] gamma: 缩放参数 (如果提供), 形状应为 [feature_dim] beta: 偏移参数 (如果提供), 形状应为 [feature_dim] eps: 防止除零错误的小常数
返回
归一化后的 NumPy 数组, 形状与输入 x 相同.
源代码位于: src/llm/core/layer_norm.py
Embeddings and Positional Encoding¶
embedding
¶
EmbeddingLayer
¶
Bases: Module
Combines token embeddings with positional encodings.
The layer first embeds input token IDs into dense vectors, then scales these embeddings by the square root of the hidden size, and finally adds positional encodings.
源代码位于: src/llm/core/embedding.py
forward
¶
Forward pass of the EmbeddingLayer.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
input_ids
|
Tensor
|
Tensor of token IDs of shape (batch_size, seq_len). |
必需 |
start_pos
|
int
|
Initial position index for the sequence. |
0
|
position_ids
|
Tensor
|
Explicit position IDs. |
None
|
返回:
| 类型 | 描述 |
|---|---|
Tensor
|
torch.Tensor: Tensor of embeddings with positional encodings, of shape (batch_size, seq_len, hidden_size). |
源代码位于: src/llm/core/embedding.py
positional_encoding
¶
PositionalEncoding
¶
Bases: Module
Implements Positional Encoding for Transformer models.
Supports both sinusoidal (fixed) and learned positional embeddings. Positional information is added to the input embeddings to provide order awareness.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
hidden_size
|
int
|
The dimension of the model's hidden states. |
必需 |
max_seq_len
|
int
|
Maximum sequence length supported. Defaults to 512. |
512
|
dropout_p
|
float
|
Dropout probability applied after adding positional signal. Defaults to 0.1. |
0.1
|
learned
|
bool
|
If True, uses learned embeddings; otherwise sinusoidal. Defaults to False. |
False
|
device
|
device | None
|
Device to place parameters on. |
None
|
dtype
|
dtype | None
|
Data type for parameters. |
None
|
源代码位于: src/llm/core/positional_encoding.py
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | |
forward
¶
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
x
|
Tensor
|
Tensor, shape [batch_size, seq_len, hidden_size] |
必需 |
start_pos
|
int
|
Initial position index for the sequence (used if position_ids is None). |
0
|
position_ids
|
Tensor | None
|
Optional Tensor of shape [batch_size, seq_len] containing explicit position indices. |
None
|
源代码位于: src/llm/core/positional_encoding.py
rope
¶
Rotary Position Embedding (RoPE) Module.
Implements RoPE with scaling support for extended context lengths. Supports linear scaling, dynamic scaling, and NTK-aware scaling.
Reference: https://arxiv.org/abs/2104.09864
RotaryPositionEmbedding
¶
Bases: Module
Rotary Position Embedding (RoPE).
Encodes position information by rotating query and key vectors.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
dim
|
int
|
Dimension of the embedding (typically head_dim) |
必需 |
max_seq_len
|
int
|
Maximum sequence length for precomputed embeddings |
2048
|
base
|
float
|
Base for computing rotation frequencies (default: 10000) |
10000.0
|
scaling_type
|
str | None
|
Type of RoPE scaling: None, 'linear', 'dynamic', 'ntk' |
None
|
scaling_factor
|
float
|
Scaling factor for extended context (default: 1.0) |
1.0
|
device
|
device | str | None
|
Device for the embedding |
None
|
dtype
|
dtype | None
|
Data type for the embedding |
None
|
源代码位于: src/llm/core/rope.py
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | |
forward
¶
Apply rotary position embedding to query and key tensors.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
q
|
Tensor
|
Query tensor of shape [batch, heads, seq_len, head_dim] |
必需 |
k
|
Tensor
|
Key tensor of shape [batch, heads, seq_len, head_dim] |
必需 |
position_ids
|
Tensor | None
|
Optional position indices [batch, seq_len] |
None
|
返回:
| 类型 | 描述 |
|---|---|
tuple[Tensor, Tensor]
|
Tuple of (rotated_q, rotated_k) |
源代码位于: src/llm/core/rope.py
rotate_half
¶
apply_rotary_pos_emb
¶
Apply rotary position embedding to a tensor.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
x
|
Tensor
|
Input tensor of shape [..., seq_len, dim] |
必需 |
cos
|
Tensor
|
Cosine embeddings |
必需 |
sin
|
Tensor
|
Sine embeddings |
必需 |
返回:
| 类型 | 描述 |
|---|---|
Tensor
|
Rotated tensor of the same shape |
源代码位于: src/llm/core/rope.py
get_rope_scaling_factor
¶
Compute appropriate RoPE scaling factor.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
seq_len
|
int
|
Current sequence length |
必需 |
max_trained_len
|
int
|
Maximum length the model was trained on |
必需 |
scaling_type
|
str
|
Type of scaling ('linear' or 'dynamic') |
'linear'
|
返回:
| 类型 | 描述 |
|---|---|
float
|
Scaling factor |
源代码位于: src/llm/core/rope.py
alibi
¶
ALiBi (Attention with Linear Biases) Module.
Implements ALiBi, a simple position encoding method that adds linear biases to attention scores based on token distance.
Reference: https://arxiv.org/abs/2108.12409
ALiBiPositionBias
¶
Bases: Module
ALiBi Position Bias Module.
Generates position-dependent biases to be added to attention scores.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
num_heads
|
int
|
Number of attention heads |
必需 |
max_seq_len
|
int
|
Maximum sequence length for cached bias |
2048
|
device
|
device | str | None
|
Target device |
None
|
dtype
|
dtype | None
|
Target data type |
None
|
源代码位于: src/llm/core/alibi.py
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | |
forward
¶
Add ALiBi bias to attention scores.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
attention_scores
|
Tensor
|
Attention scores of shape [batch, heads, seq_len, seq_len] |
必需 |
返回:
| 类型 | 描述 |
|---|---|
Tensor
|
Attention scores with ALiBi bias added |
源代码位于: src/llm/core/alibi.py
get_bias
¶
Get ALiBi bias matrix for given sequence length.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
seq_len
|
int
|
Sequence length |
必需 |
device
|
device | str | None
|
Target device |
None
|
dtype
|
dtype | None
|
Target data type |
None
|
返回:
| 类型 | 描述 |
|---|---|
Tensor
|
Bias tensor of shape [1, num_heads, seq_len, seq_len] |
源代码位于: src/llm/core/alibi.py
get_alibi_slopes
¶
Compute ALiBi slopes for each attention head.
Slopes form a geometric sequence: 2^(-8/n), 2^(-16/n), ..., 2^(-8) where n is the number of heads.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
num_heads
|
int
|
Number of attention heads |
必需 |
返回:
| 类型 | 描述 |
|---|---|
Tensor
|
Tensor of shape [num_heads] containing slopes |
源代码位于: src/llm/core/alibi.py
build_alibi_bias
¶
Build the ALiBi bias matrix.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
num_heads
|
int
|
Number of attention heads |
必需 |
seq_len
|
int
|
Sequence length |
必需 |
device
|
device | str | None
|
Target device |
None
|
dtype
|
dtype | None
|
Target data type |
None
|
返回:
| 类型 | 描述 |
|---|---|
Tensor
|
Tensor of shape [1, num_heads, seq_len, seq_len] |
源代码位于: src/llm/core/alibi.py
PEFT Helpers¶
The unified PEFT_REGISTRY lives in
llm.core.peft; these are the standalone helper modules for
the individual methods.
lora
¶
LoRA (Low-Rank Adaptation) Module.
Implements parameter-efficient fine-tuning by adding trainable low-rank matrices to frozen linear layers.
Reference: https://arxiv.org/abs/2106.09685
LoRALinear
¶
Bases: Module
LoRA-adapted linear layer.
Wraps a frozen nn.Linear and adds trainable low-rank matrices A and B. Output: base_output + (input @ A) @ B * scaling
Snapshot of scaling, set by
:func:disable_lora, cleared by :func:enable_lora.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
base_layer
|
Linear
|
The original nn.Linear layer to adapt (will be frozen) |
必需 |
rank
|
int
|
Rank of the low-rank matrices (default: 8) |
8
|
alpha
|
float
|
Scaling factor (default: 16.0) |
16.0
|
dropout
|
float
|
Dropout probability for LoRA path (default: 0.0) |
0.0
|
源代码位于: src/llm/core/lora.py
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | |
forward
¶
Forward pass: frozen base + LoRA adaptation.
merge_weights
¶
Merge LoRA weights into the base layer for efficient inference.
Folds ΔW · scaling into base_layer.weight and then
disables the adapter path (scaling → 0) so that
:meth:forward continues to produce the same output as
before merging — the wrapper becomes a pure pass-through to the
already-merged base. Without disabling the path the adapter
would be double-counted on every forward (a roughly 2x-strength
model at serve time).
:meth:unmerge_weights restores both the original base weight
and this scaling snapshot.
Idempotent: a second call while already merged is a no-op. Re-running
the fold would re-store _merged_scaling = self.scaling where
scaling is already 0 (post first merge), so the re-fold no-ops
AND the snapshot becomes 0 — the later unmerge_weights then
restores scaling=0 and leaves the base permanently folded at 2x
adapter strength (RIL ISS-159).
源代码位于: src/llm/core/lora.py
unmerge_weights
¶
Unmerge LoRA weights from the base layer.
Restores the pre-merge base weight and re-enables the adapter
path. No-op if :meth:merge_weights was never called.
源代码位于: src/llm/core/lora.py
apply_lora
¶
Apply LoRA to specified linear layers in a model.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
model
|
Module
|
The model to adapt |
必需 |
rank
|
int
|
LoRA rank |
8
|
alpha
|
float
|
LoRA alpha (scaling = alpha / rank) |
16.0
|
dropout
|
float
|
Dropout probability for LoRA path |
0.0
|
target_modules
|
list[str] | None
|
List of module name patterns to target. If None, targets all nn.Linear layers. |
None
|
返回:
| 类型 | 描述 |
|---|---|
Module
|
The model with LoRA applied (modified in-place) |
源代码位于: src/llm/core/lora.py
merge_lora
¶
Merge all LoRA weights into base layers for efficient inference.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
model
|
Module
|
Model with LoRA layers |
必需 |
返回:
| 类型 | 描述 |
|---|---|
Module
|
The model with merged weights (modified in-place) |
源代码位于: src/llm/core/lora.py
unmerge_lora
¶
Unmerge all LoRA weights from base layers.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
model
|
Module
|
Model with merged LoRA layers |
必需 |
返回:
| 类型 | 描述 |
|---|---|
Module
|
The model with unmerged weights (modified in-place) |
源代码位于: src/llm/core/lora.py
get_lora_parameters
¶
Get only LoRA parameters for optimizer.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
model
|
Module
|
Model with LoRA layers |
必需 |
产生:
| 类型 | 描述 |
|---|---|
Parameter
|
LoRA parameters (lora_A and lora_B) |
源代码位于: src/llm/core/lora.py
count_lora_parameters
¶
Count trainable and total parameters in a model with LoRA.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
model
|
Module
|
Model with LoRA layers |
必需 |
返回:
| 类型 | 描述 |
|---|---|
tuple[int, int]
|
Tuple of (trainable_params, total_params) |
源代码位于: src/llm/core/lora.py
disable_lora
¶
Disable LoRA by setting scaling to 0.
enable_lora
¶
Re-enable LoRA after disabling.
qlora
¶
QLoRA (Quantized LoRA) Module.
Implements memory-efficient fine-tuning by combining: 1. 4-bit quantization of base model weights (NF4 format) 2. Low-rank adaptation (LoRA) in full precision
Reference: https://arxiv.org/abs/2305.14314
QLoRALinear
¶
Bases: Module
QLoRA-adapted linear layer.
Combines 4-bit quantized base weights with full-precision LoRA adapters. Memory usage: ~4x reduction for base weights.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
base_layer
|
Linear
|
Original nn.Linear layer to adapt (will be quantized) |
必需 |
rank
|
int
|
LoRA rank (default: 8) |
8
|
alpha
|
float
|
LoRA alpha (default: 16.0) |
16.0
|
dropout
|
float
|
Dropout for LoRA path (default: 0.0) |
0.0
|
block_size
|
int
|
Quantization block size (default: 64) |
64
|
源代码位于: src/llm/core/qlora.py
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | |
forward
¶
Forward pass with dequantized base + LoRA adaptation.
源代码位于: src/llm/core/qlora.py
quantize_nf4
¶
Quantize weights to 4-bit NF4 format with block-wise scaling.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
weight
|
Tensor
|
Weight tensor to quantize [out_features, in_features] |
必需 |
block_size
|
int
|
Number of elements per quantization block |
64
|
返回:
| 类型 | 描述 |
|---|---|
Tensor
|
Tuple of (quantized_indices, scales) |
Tensor
|
|
tuple[Tensor, Tensor]
|
|
源代码位于: src/llm/core/qlora.py
dequantize_nf4
¶
Dequantize 4-bit NF4 indices back to floating point.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
indices
|
Tensor
|
Quantized indices (uint8) |
必需 |
scales
|
Tensor
|
Block-wise scales |
必需 |
original_shape
|
tuple[int, ...]
|
Original weight shape |
必需 |
block_size
|
int
|
Block size used during quantization |
64
|
dtype
|
dtype
|
Target dtype for dequantized weights |
float16
|
返回:
| 类型 | 描述 |
|---|---|
Tensor
|
Dequantized weight tensor |
源代码位于: src/llm/core/qlora.py
apply_qlora
¶
Apply QLoRA to specified linear layers in a model.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
model
|
Module
|
The model to adapt |
必需 |
rank
|
int
|
LoRA rank |
8
|
alpha
|
float
|
LoRA alpha (scaling = alpha / rank) |
16.0
|
dropout
|
float
|
Dropout probability for LoRA path |
0.0
|
block_size
|
int
|
Quantization block size |
64
|
target_modules
|
list[str] | None
|
List of module name patterns to target. If None, targets all nn.Linear layers. |
None
|
返回:
| 类型 | 描述 |
|---|---|
Module
|
The model with QLoRA applied (modified in-place) |
源代码位于: src/llm/core/qlora.py
get_qlora_parameters
¶
Get only QLoRA trainable parameters for optimizer.
adalora
¶
AdaLoRA (Adaptive LoRA) module.
SVD-form parameter-efficient fine-tuning. The increment matrix is
parameterized as ΔW = P · diag(λ · mask) · Q where P, Q are
orthonormalized on every forward (QR decomposition) and λ is a
learnable diagonal. A buffer mask lets the future pruning slice
zero out low-importance components without a public-API break.
Reference: Zhang et al., 2023 — Adaptive Budget Allocation for Parameter-Efficient Fine-Tuning, arXiv:2303.10512.
AdaLoRALinear
¶
Bases: Module
AdaLoRA-adapted linear layer with SVD-form parameterization.
The increment matrix is parameterized as ΔW = P · diag(λ · mask)
· Q where:
P: (out_features, init_rank)— left singular vectors, trainable.Q: (init_rank, in_features)— right singular vectors, trainable.λ: (init_rank,)— singular values, trainable.mask: (init_rank,)— binary mask registered as a buffer (not a Parameter) so the future pruning slice can write to it without breaking autograd.
Forward pass:
- Orthonormalize P via QR →
P̃. - Orthonormalize Q via QR on
Qᵀ→Q̃(rows of Q̃ are orthonormal — i.e.Q̃ Q̃ᵀ = I). - Compute
ΔW = P̃ · diag(λ · mask) · Q̃of shape(out_features, in_features). - Return
base(x) + scaling · x · ΔWᵀ.
At initialization λ = 0 so ΔW = 0 exactly — the layer
behaves identically to the base layer, matching LoRA's
zero-initialized-B invariant.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
base_layer
|
Linear
|
The original |
必需 |
init_rank
|
int
|
Initial rank budget (upper bound on the number of
singular components). Must satisfy |
12
|
target_rank
|
int | None
|
Final target rank after pruning. Stored on the layer so the future pruning slice can consult it. This foundation slice does not prune — the mask starts all-ones. |
None
|
alpha
|
float
|
Scaling factor. Forward scales |
32.0
|
dropout
|
float
|
Dropout probability for the LoRA path. |
0.0
|
orth_reg_weight
|
float
|
Default weight for the orthogonality
regularization. Stored on the layer so trainers can read
it without hard-coding; the loss itself is opt-in (call
:meth: |
0.5
|
源代码位于: src/llm/core/adalora.py
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 | |
effective_rank
property
¶
Number of currently active (masked-in) components.
Reads through self.mask so the future pruning slice can
drive this property by zeroing mask entries — no other
bookkeeping needed.
trainable_parameters
property
¶
Number of trainable AdaLoRA parameters (P + Q + λ).
forward
¶
Forward pass: base(x) + scaling · x · ΔWᵀ.
源代码位于: src/llm/core/adalora.py
orth_reg_loss
¶
Orthogonality regularization loss.
Per the AdaLoRA paper (arXiv:2303.10512), the loss penalises deviation from orthonormality of the learned parameters::
||P^T P - I||_F^2 + ||Q Q^T - I||_F^2
Returns a scalar (sum of both terms). Trainers add this to the
task loss (scaled by :attr:orth_reg_weight) to keep P and Q
well-conditioned during training.
The loss is computed over lora_P / lora_Q themselves —
the matrices the optimizer updates — NOT over the QR factors used
in forward (RIL ISS-157). Those factors are orthonormal by
construction, so penalising them returns ~float noise no matter
how degenerate the underlying P/Q are: a regularizer that cannot
distinguish a rank-1 P from a perfectly orthonormal one is dead
weight. Penalising the raw parameters gives gradient descent a
real signal to keep them well-conditioned.
源代码位于: src/llm/core/adalora.py
merge_weights
¶
Merge ΔW into the base layer for efficient inference.
Folds ΔW · scaling into base_layer.weight and then
disables the adapter path (scaling → 0) so the layer's
forward — which early-returns the base when
self.scaling == 0.0 — stays equivalent to the folded base
instead of double-counting the adapter at serve time. The
companion :meth:unmerge_weights restores both the original
base weight and this scaling snapshot for continued training.
Idempotent: a second call while already merged is a no-op (mirrors
the LoRA fix — see :meth:llm.core.lora.LoRALinear.merge_weights).
Re-running the fold would re-store _merged_scaling =
self.scaling where scaling is already 0 (post first merge),
so the re-fold no-ops AND the snapshot becomes 0 — the later
unmerge_weights then restores scaling=0 and leaves the base
permanently folded at 2x adapter strength (RIL ISS-159).
源代码位于: src/llm/core/adalora.py
unmerge_weights
¶
Unmerge ΔW from the base layer.
Restores the pre-merge base weight and re-enables the adapter
path. No-op if :meth:merge_weights was never called.
源代码位于: src/llm/core/adalora.py
compute_importance_scores
¶
Per-component importance scores, one per singular value.
Per the AdaLoRA paper (Algorithm 1, line 7), the combined
importance score is |λ_i| · |∂L/∂λ_i|. Trainers compute
the EMA of |∂L/∂λ_i| themselves (the optimizer owns
gradient statistics), then pass it here.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
gradient_ema
|
Tensor | None
|
Optional EMA tensor of shape
|
None
|
返回:
| 类型 | 描述 |
|---|---|
Tensor
|
Tensor of shape |
Tensor
|
component. Components with higher scores carry more of |
Tensor
|
the model's expressive capacity and should be kept under |
Tensor
|
pruning. |
源代码位于: src/llm/core/adalora.py
prune_to_rank
¶
Zero out mask entries for the lowest-importance components.
Mutates :attr:mask in-place so that exactly target_rank
entries remain 1.0 and the rest are 0.0. The kept
entries are the target_rank components with highest
importance score (see :meth:compute_importance_scores).
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
target_rank
|
int
|
Number of components to keep. Must satisfy
|
必需 |
scores
|
Tensor | None
|
Optional pre-computed importance scores of shape
|
None
|
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
if |
源代码位于: src/llm/core/adalora.py
update_budget
¶
Return the rank budget for the current training step.
Linear schedule from init_rank at tinit to
target_rank at tfinal. Useful for periodic pruning
during fine-tuning: train at full rank through warmup, then
gradually reallocate the budget down to target_rank.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
current_step
|
int
|
The current training step (≥ 0). |
必需 |
tinit
|
int
|
Step at and before which the budget is held at
|
必需 |
tfinal
|
int
|
Step at and after which the budget is held at
|
必需 |
返回:
| 类型 | 描述 |
|---|---|
int
|
Integer rank budget to use for this step. Round to |
int
|
|
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
if |
源代码位于: src/llm/core/adalora.py
AdaLoRAGradientEMA
¶
Per-layer EMA of |∂L/∂λ| for AdaLoRA's importance scoring.
Implements the EMA half of AdaLoRA Algorithm 1 (Zhang et al. 2023, page 4)::
I_avg_i <- alpha * I_avg_i + (1 - alpha) * |dL/dlambda_i|
The tracker is constructed against a model that already has
AdaLoRALinear layers in place. After each backward pass, the
trainer calls :meth:update to fold the current gradient into the
EMA. The result is consumed by :func:prune_adalora (via
:meth:as_dict) to weight components by their combined
|λ| · |∂L/∂λ| score during pruning.
State is checkpointable through :meth:state_dict /
:meth:load_state_dict, both keyed by the layer's qualified
name ("0", "layer1.attn", ...). id(layer) is not
stable across pickle roundtrips, so the checkpoint key must be a
structural path.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
model
|
Module
|
The model whose |
必需 |
alpha
|
float
|
EMA smoothing factor (the weight on the previous EMA).
|
0.95
|
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
if |
源代码位于: src/llm/core/adalora.py
634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 | |
update
¶
Fold |∂L/∂λ| from each layer's last backward into the EMA.
Layers whose lora_lambda.grad is None (frozen, or no
path through them this step) are left untouched — only the
components training actually drove get smoothed in.
源代码位于: src/llm/core/adalora.py
as_dict
¶
Return {id(layer): ema_tensor} for :func:prune_adalora.
The trainer passes this directly as gradient_emas= to
:func:prune_adalora. id() is fine here because the
tracker and the prune call share the same Python process; it
is only the checkpoint roundtrip that needs a stable key.
源代码位于: src/llm/core/adalora.py
state_dict
¶
Return a serializable snapshot keyed by qualified name.
Tensors are detached so a subsequent load_state_dict on a
fresh tracker doesn't keep a reference to the autograd graph.
源代码位于: src/llm/core/adalora.py
load_state_dict
¶
Restore EMA tensors from a :meth:state_dict snapshot.
Unknown keys (e.g. from a stale checkpoint where the model has
since been pruned of a layer) are silently ignored. None
is a no-op so a fresh checkpoint doesn't crash the trainer.
源代码位于: src/llm/core/adalora.py
apply_adalora
¶
apply_adalora(model, init_rank=12, target_rank=None, alpha=32.0, dropout=0.0, target_modules=None, orth_reg_weight=0.5)
Apply AdaLoRA to specified linear layers in a model.
Mirrors :func:llm.core.lora.apply_lora so swapping LoRA → AdaLoRA
in user code is a one-import change. target_rank is stored on
each layer but does not trigger pruning in this foundation
slice — that lands in the follow-up.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
model
|
Module
|
The model to adapt. Modified in-place. |
必需 |
init_rank
|
int
|
Initial rank budget. |
12
|
target_rank
|
int | None
|
Final target rank after pruning (deferred). |
None
|
alpha
|
float
|
Scaling factor ( |
32.0
|
dropout
|
float
|
Dropout probability for the AdaLoRA path. |
0.0
|
target_modules
|
list[str] | None
|
List of module-name substring patterns. If
|
None
|
orth_reg_weight
|
float
|
Default weight for orthogonality regularization. |
0.5
|
返回:
| 类型 | 描述 |
|---|---|
Module
|
The same model, modified in-place. |
源代码位于: src/llm/core/adalora.py
merge_adalora
¶
Merge all AdaLoRA deltas into the corresponding base layers.
unmerge_adalora
¶
Unmerge all AdaLoRA deltas from the corresponding base layers.
get_adalora_parameters
¶
Yield every AdaLoRA P, Q, and λ parameter in the model.
Trainers pass this to the optimizer so only the AdaLoRA path is updated — the base weights stay frozen.
源代码位于: src/llm/core/adalora.py
count_adalora_parameters
¶
Return (trainable_params, total_params) for a model with AdaLoRA.
Trainable count follows whatever requires_grad is set on every
parameter — the base layer weights are frozen at construction, so
trainable_params will equal the sum of all AdaLoRA
trainable_parameters plus any other unfrozen parameters the
caller has chosen to add (e.g. norms).
源代码位于: src/llm/core/adalora.py
disable_adalora
¶
Disable AdaLoRA by setting scaling to 0 (model falls back to base).
源代码位于: src/llm/core/adalora.py
enable_adalora
¶
Re-enable AdaLoRA after :func:disable_adalora.
源代码位于: src/llm/core/adalora.py
prune_adalora
¶
Walk every AdaLoRALinear in model and prune to a target rank.
Two calling modes:
-
Explicit target rank::
prune_adalora(model, target_rank=8)
Every AdaLoRALinear layer is pruned to target_rank
(subject to the per-layer effective_rank upper bound).
-
Budget schedule::
prune_adalora(model, schedule=(tinit, tfinal), current_step=step)
Each layer is pruned to the rank that
layer.update_budget(step, tinit, tfinal) returns — i.e.
the budget is re-evaluated per call, so a training loop can
invoke this helper periodically and the rank shrinks over time.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
model
|
Module
|
Model containing one or more |
必需 |
target_rank
|
int | None
|
Explicit rank to prune every layer to. Mutually
exclusive with |
None
|
schedule
|
tuple[int, int] | None
|
|
None
|
current_step
|
int | None
|
Current training step, used only when
|
None
|
gradient_emas
|
dict[int, Tensor] | None
|
Optional dict mapping |
None
|
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
if neither |
源代码位于: src/llm/core/adalora.py
553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 | |
bitfit
¶
BitFit (Bias-Term Fine-Tuning).
The simplest parameter-efficient fine-tuning method: train only the
bias parameters, freeze everything else. Unlike LoRA / AdaLoRA / IA³,
BitFit adds no new parameters and wraps no modules — it just toggles
requires_grad on every bias in the model.
Per the paper (Ben-Zaken et al. 2021), all bias parameters are
trainable: attention Q/K/V/O projection biases, FFN intermediate /
output projection biases, and LayerNorm / RMSNorm biases. The user
can opt to filter by target_modules (substring match on the
parameter's qualified name) to bias-select a subset — e.g. only
attention biases — but the default is to train every bias.
The helper API mirrors LoRA / AdaLoRA / IA³ so swapping PEFT methods in user code is a one-import change:
from llm.core.bitfit import apply_bitfit, get_bitfit_parameters
apply_bitfit(model)
optimizer = torch.optim.AdamW(get_bitfit_parameters(model), lr=1e-3)
Per-model cost: O(num_biases) trainable params — typically
<0.1% of total parameters. BitFit is the lightest possible PEFT
method: no math, no wrappers, no scheduler.
Reference: Ben-Zaken et al., 2021 — BitFit: Simple Parameter-efficient Fine-tuning for Transformer-based Masked Language-models.
apply_bitfit
¶
Freeze every parameter, then enable gradients on every bias.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
model
|
Module
|
The model to adapt (modified in-place). |
必需 |
target_modules
|
list[str] | None
|
Optional list of module-name substring patterns.
A bias is trainable only if its qualified name (e.g.
|
None
|
返回:
| 类型 | 描述 |
|---|---|
Module
|
The model with BitFit applied (modified in-place). |
Note
BitFit saves the original requires_grad state on the model
under _bitfit_original_requires_grad so :func:unapply_bitfit
can restore it. Calling :func:apply_bitfit twice without an
intervening :func:unapply_bitfit re-saves on the second call
(so the snapshot always reflects the pre-BitFit state).
源代码位于: src/llm/core/bitfit.py
unapply_bitfit
¶
Restore the pre-BitFit requires_grad state.
Reverses :func:apply_bitfit — every parameter is set back to
whatever its requires_grad was before :func:apply_bitfit was
called. No-op if :func:apply_bitfit was never called.
源代码位于: src/llm/core/bitfit.py
get_bitfit_parameters
¶
Yield every trainable bias parameter.
Use this to wire the optimizer
torch.optim.AdamW(get_bitfit_parameters(model), lr=...)
After :func:apply_bitfit, exactly the bias parameters are
trainable, so this is equivalent to iter(model.parameters())
filtered by p.requires_grad — but we re-check the .bias
suffix explicitly so the helper remains correct if a user
manually enables a non-bias parameter after applying BitFit
(the helper still yields only biases, not the non-bias ones).
Substring matching is intentionally avoided: fc_with_bias.weight
contains the substring bias but is not a bias parameter.
源代码位于: src/llm/core/bitfit.py
count_bitfit_parameters
¶
Count trainable vs. total parameters in a BitFit-adapted model.
返回:
| 类型 | 描述 |
|---|---|
int
|
|
int
|
is |
Before :func:apply_bitfit is called, the helper reports whatever
requires_grad state the model was constructed with (typically
all-trainable, since :class:nn.Linear defaults to True).
源代码位于: src/llm/core/bitfit.py
is_bitfit_applied
¶
Return True if :func:apply_bitfit was called on this model
and not yet reversed by :func:unapply_bitfit.
Useful for checkpoint validation: if a checkpoint claims to be
BitFit-adapted, the snapshot attribute should be present (or
absent, if the user already called unapply_bitfit).
源代码位于: src/llm/core/bitfit.py
ia3
¶
IA³ (Infused Adapter by Inhibiting and Amplifying Inner Activations).
A parameter-efficient fine-tuning method that wraps a frozen
nn.Linear with a single trainable vector that multiplicatively
scales the output. IA³ is the multiplicative counterpart to LoRA's
additive design — instead of adding ΔW · x it scales the existing
output W · x element-wise on the output dimension.
Per-layer cost: out_features trainable parameters (vs. LoRA's
rank * (in_features + out_features) and AdaLoRA's init_rank *
(in_features + out_features)). At out_features=4096 and
rank=8, in_features=4096 that is ~4k vs. ~65k parameters per
adapted linear — typically two orders of magnitude fewer than LoRA.
Forward
y = (W · x + b) * l
where l is a learned vector of shape (out_features,)
broadcast across batch and sequence dims.
Initialization
l ← ones so the wrapped layer starts as the identity transform
— the model's existing forward is preserved at step 1, which
avoids the chicken-and-egg problem that a zero-init would cause.
Merge for inference
W ← W * l[None, :] and b ← b * l. The learned vector folds
into the base weight and can be discarded — no extra params at
serve time, no extra matmul. Symmetric unmerge_weights reverses
the merge so the same model can be checkpointed pre- and post-merge.
Reference: Liu et al., 2022 — Few-Shot Parameter-Efficient Fine-Tuning
is Better and Cheaper than In-Context Learning, arXiv:2205.05638
(aka "T-Few"). The paper applies IA³ to attention K/V/output and FFN
intermediate projections — the helper API mirrors LoRA so swapping
apply_lora for apply_ia3 is a one-import change.
IA3Linear
¶
Bases: Module
Wrap a frozen nn.Linear with a trainable multiplicative scale.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
base_layer
|
Linear
|
The original |
必需 |
init_scale
|
float
|
Initial value of the multiplicative scale. Defaults
to |
1.0
|
源代码位于: src/llm/core/ia3.py
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | |
trainable_parameters
property
¶
Number of trainable IA³ parameters (just ia3_l.numel()).
forward
¶
Forward pass: frozen base output, multiplicatively scaled.
源代码位于: src/llm/core/ia3.py
merge_weights
¶
Merge the multiplicative scale into the base weight for inference.
After this call, self.base_layer.weight already contains
the scale (W * l[None, :]) and self.ia3_l is set to
ones so the wrapper is the identity on top of the already-scaled
base. unmerge_weights reverses the operation, restoring
both the original ia3_l snapshot and the pre-merge base
weight — useful for checkpoint roundtrip where the same model
needs to be saved both pre- and post-merge.
源代码位于: src/llm/core/ia3.py
unmerge_weights
¶
Reverse :meth:merge_weights — restores both the saved
ia3_l snapshot and the pre-merge base weight. No-op if
:meth:merge_weights was never called.
源代码位于: src/llm/core/ia3.py
apply_ia3
¶
Apply IA³ to specified linear layers in a model.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
model
|
Module
|
The model to adapt (modified in-place). |
必需 |
init_scale
|
float
|
Initial value of the multiplicative scale (passed
through to :class: |
1.0
|
target_modules
|
list[str] | None
|
List of module-name substring patterns. If
|
None
|
返回:
| 类型 | 描述 |
|---|---|
Module
|
The model with IA³ applied (modified in-place). |
源代码位于: src/llm/core/ia3.py
merge_ia3
¶
Merge every IA³ scale into the wrapped base weight.
After this, the model is identical to the original at inference
but no longer has trainable IA³ params. Reversible via
:func:unmerge_ia3.
源代码位于: src/llm/core/ia3.py
unmerge_ia3
¶
Reverse :func:merge_ia3 — restores the trained ia3_l as the
active scale. Useful for checkpoint roundtrip.
源代码位于: src/llm/core/ia3.py
get_ia3_parameters
¶
Yield every IA³ trainable parameter — one ia3_l per wrapper.
Use this to wire the optimizer
torch.optim.Adam(get_ia3_parameters(model), lr=...)
源代码位于: src/llm/core/ia3.py
count_ia3_parameters
¶
Count trainable vs. total parameters in an IA³-adapted model.
返回:
| 类型 | 描述 |
|---|---|
int
|
|
int
|
is |
源代码位于: src/llm/core/ia3.py
disable_ia3
¶
Disable IA³ at inference — sets every ia3_l to all-ones so
the wrapper is the identity transform. Use this when you want to
evaluate the base model behaviour without un-wrapping.
源代码位于: src/llm/core/ia3.py
enable_ia3
¶
Re-enable IA³ after :func:disable_ia3 — restores the saved
ia3_l snapshot. No-op if disable_ia3 was never called.
源代码位于: src/llm/core/ia3.py
adapter
¶
Adapter Layers (Houlsby et al. 2019).
Parameter-efficient fine-tuning via bottleneck modules inserted into transformer blocks. The adapter is a small feed-forward block with a residual connection - the base Linear is frozen, and only the adapter parameters train.
Per the original paper, adapters are inserted:
``x → Linear → activation → Linear → + residual → output``
i.e. a down-projection (to a small bottleneck dim), a non-linearity, and an up-projection back to the hidden dim, summed with the base output. The up-projection is zero-initialized so the adapter is the identity transform at step 1 - no chicken-and-egg training stall.
Per-layer trainable cost: hidden_size x bottleneck_dim +
bottleneck_dim x hidden_size + bottleneck_dim + hidden_size
(down weight + up weight + down bias + up bias). At
hidden_size=4096, bottleneck_dim=64 that's
2 x 4096 x 64 + 64 + 4096 ≈ 528k params per adapted Linear - vs.
LoRA's rank x (in + out) = 8 x (4096 + 4096) ≈ 65k and IA³'s
4096. Adapters are usually bigger than LoRA / IA³ but smaller
than full fine-tuning.
Forward
y = base_linear(x) + up(activation(down(base_linear(x))))
Initialization
down: Kaiming uniform (standard Linear init).up: zeros - so the adapter contributes 0 to the output at step 1, and the wrapper is the identity on top of the base.activation:nn.ReLU(the original paper usesReLU; later work usesGELUorTanh- picked here to match Houlsby 2019).
The helper API (apply_adapter / merge_adapter /
unmerge_adapter / get_adapter_parameters /
count_adapter_parameters / disable_adapter /
enable_adapter) mirrors LoRA / IA³ / BitFit so swapping PEFT
methods in user code is a one-import change. Note that
merge_adapter is a near no-op for adapters - the up-projection
being zero means the adapter contributes nothing, so merging the
adapter into the base would just add zeros. The function is kept
for API parity.
Reference: Houlsby et al., 2019 - Parameter-Efficient Transfer Learning for NLP, arXiv:1902.00751. The bottleneck-only-after-FFN variant (Pfeiffer et al. 2020) and the Compacter / MAD-X decompositions are deliberate follow-ups.
AdapterLinear
¶
Bases: Module
Wrap a frozen nn.Linear with a bottleneck adapter on the output.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
base_layer
|
Linear
|
The original |
必需 |
bottleneck_dim
|
int
|
Width of the adapter's hidden dim. Smaller values reduce trainable parameters; typical values are 8-256 depending on the hidden size. |
必需 |
activation
|
type[Module]
|
Non-linearity class (defaults to |
ReLU
|
属性:
| 名称 | 类型 | 描述 |
|---|---|---|
_original_up_weight |
Tensor | None
|
Snapshot of up-projection weight, set by
:func: |
_original_up_bias |
Tensor | None
|
Snapshot of up-projection bias, set/cleared
alongside |
源代码位于: src/llm/core/adapter.py
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | |
trainable_parameters
property
¶
Number of trainable adapter parameters (down + up weights + biases).
forward
¶
Forward pass: frozen base output + residual adapter output.
源代码位于: src/llm/core/adapter.py
merge_weights
¶
No-op for adapters.
Unlike LoRA / IA³ the adapter has no math to fold into the
base weight - the up-projection being zero means the adapter
contributes zero to the output. merge_weights is kept
for API parity with the other PEFT helpers; it does nothing.
源代码位于: src/llm/core/adapter.py
unmerge_weights
¶
apply_adapter
¶
Apply adapter bottleneck modules to specified linear layers.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
model
|
Module
|
The model to adapt (modified in-place). |
必需 |
bottleneck_dim
|
int
|
Width of the adapter's hidden dim (passed
through to :class: |
64
|
target_modules
|
list[str] | None
|
List of module-name substring patterns. If
|
None
|
返回:
| 类型 | 描述 |
|---|---|
Module
|
The model with adapters applied (modified in-place). |
源代码位于: src/llm/core/adapter.py
merge_adapter
¶
No-op for adapters - kept for API parity with LoRA / IA³.
Unlike LoRA / IA³, the adapter has no math to fold into the base weight. The up-projection is zero-initialized, so the adapter contributes zero to the output unless the user trained it.
This function is provided so that apply_adapter /
merge_adapter / unmerge_adapter follow the same call
pattern as the other PEFT helpers.
源代码位于: src/llm/core/adapter.py
unmerge_adapter
¶
No-op for adapters - mirror of :func:merge_adapter.
get_adapter_parameters
¶
Yield every trainable adapter parameter - down + up weights + biases per wrapper, nothing from the base Linear.
源代码位于: src/llm/core/adapter.py
count_adapter_parameters
¶
Count trainable vs. total parameters in an adapter-adapted model.
源代码位于: src/llm/core/adapter.py
disable_adapter
¶
Disable adapters by zeroing the up-projection (so the adapter contributes zero to the output).
Saves the up-projection weight / bias under _original_up_weight
/ _original_up_bias so :func:enable_adapter can restore them.
源代码位于: src/llm/core/adapter.py
enable_adapter
¶
Re-enable adapters after :func:disable_adapter - restores the
saved up-projection snapshot. No-op if disable_adapter was
never called.
源代码位于: src/llm/core/adapter.py
pfeiffer_adapter
¶
Pfeiffer Adapter (Pfeiffer et al. 2020).
Parameter-efficient fine-tuning via bottleneck modules inserted only after FFN/MLP layers, not after attention projections. The variant was introduced in Pfeiffer et al., 2020 — AdapterHub: A Framework for Adapting Transformers, arXiv:2007.07779 — and is the production default in AdapterHub / HuggingFace PEFT, roughly half the parameters of Houlsby 2019 at comparable accuracy on most tasks.
The wrapper class is the same :class:llm.core.adapter.AdapterLinear
used by Houlsby — there is no new tensor type. The only difference
between Houlsby and Pfeiffer is which linears get wrapped:
- Houlsby: every
nn.Linear(attention + MLP) - Pfeiffer: only the FFN / MLP linears (default
fc1+fc2, matching :class:llm.core.mlp.MLP)
Per the original paper, the adapter is the same bottleneck residual:
``y = base_linear(x) + up(activation(down(base_linear(x))))``
with up zero-initialized so the adapter is the identity at step 1
(no chicken-and-egg training stall).
Per-layer trainable cost: 2 * out_features * bottleneck_dim +
out_features + bottleneck_dim — identical to Houlsby's per-layer
cost. The parameter savings come from wrapping fewer layers, not
from a smaller per-layer footprint. A 2-layer transformer block with
hidden=4096 and bottleneck=64 has:
- Houlsby: 4 attention linears + 2 MLP linears = 6 wrappers ≈ 6 * (2 * 4096 * 64 + 4096 + 64) ≈ 3.2M trainable per block
- Pfeiffer: 2 MLP linears = 2 wrappers ≈ 2 * (2 * 4096 * 64 + 4096 + 64) ≈ 1.05M trainable per block
The helper API mirrors the Houlsby one (merge_* / unmerge_* /
get_*_parameters / count_*_parameters / disable_*` /enable_*) so swappingadapter→pfeiffer_adapter` in user
code is a one-import change. Internally the helpers delegate to the
Houlsby implementations — Pfeiffer wrappers **are**
:class:llm.core.adapter.AdapterLinear` instances, so there's nothing
to distinguish at runtime.
Reference: Pfeiffer et al., 2020 — AdapterHub: A Framework for Adapting Transformers, arXiv:2007.07779. The Compacter (Kronecker decomposition) and MAD-X (cross-lingual modular) variants are deliberate follow-ups; this slice ships the simple FFN-only variant.
apply_pfeiffer_adapter
¶
Apply Pfeiffer Adapter — bottleneck residual only after FFN/MLP.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
model
|
Module
|
The model to adapt (modified in-place). |
必需 |
bottleneck_dim
|
int
|
Width of the adapter's hidden dim. Forwarded
to :class: |
64
|
target_modules
|
list[str] | None
|
List of module-name substring patterns used to
pick which |
None
|
返回:
| 类型 | 描述 |
|---|---|
Module
|
The same |
Note
Internally this is a thin delegate to
:func:llm.core.adapter.apply_adapter with the FFN-only
target filter. The wrapper class is
:class:llm.core.adapter.AdapterLinear — Pfeiffer IS
Houlsby-on-MLP-only, so no new wrapper code is needed.
Unlike LoRA / IA³ / Prefix Tuning, bottleneck_dim is the
knob (rather than rank) and the up projection is
zero-initialized so the wrapper is the identity transform at
step 1.
源代码位于: src/llm/core/pfeiffer_adapter.py
merge_pfeiffer_adapter
¶
No-op for Pfeiffer — kept for API parity with LoRA / IA³.
Delegates to :func:llm.core.adapter.merge_adapter. The up
projection being zero means the adapter contributes nothing to
the output unless the user trained it, so there's nothing to
fold into the base weight.
源代码位于: src/llm/core/pfeiffer_adapter.py
unmerge_pfeiffer_adapter
¶
get_pfeiffer_parameters
¶
Yield every trainable Pfeiffer parameter.
Delegates to :func:llm.core.adapter.get_adapter_parameters.
Since both Houlsby and Pfeiffer produce :class:AdapterLinear
wrappers, this helper yields parameters from every adapter
wrapper in the model (Pfeiffer alone, Houlsby alone, or both
coexisting). For Pfeiffer-only the result is identical to
get_adapter_parameters.
源代码位于: src/llm/core/pfeiffer_adapter.py
count_pfeiffer_parameters
¶
Return (trainable, total) parameter counts.
Delegates to :func:llm.core.adapter.count_adapter_parameters.
Same caveat as :func:get_pfeiffer_parameters — counts every
adapter wrapper, not just Pfeiffer-targeted ones. Users who mix
Pfeiffer and Houlsby on the same model should call the per-
method helpers selectively.
源代码位于: src/llm/core/pfeiffer_adapter.py
disable_pfeiffer_adapter
¶
Disable Pfeiffer adapters by zeroing the up projection.
Delegates to :func:llm.core.adapter.disable_adapter. After
this call every wrapper's up.weight and up.bias are
zero, making the wrapper mathematically the identity on top of
the base. The pre-disable up-projection is snapshotted under
_original_up_weight / _original_up_bias so
:func:enable_pfeiffer_adapter can restore it.
源代码位于: src/llm/core/pfeiffer_adapter.py
enable_pfeiffer_adapter
¶
Re-enable Pfeiffer adapters after :func:disable_pfeiffer_adapter.
Delegates to :func:llm.core.adapter.enable_adapter. No-op if
disable_pfeiffer_adapter was never called (the snapshot
attribute is the sentinel).
源代码位于: src/llm/core/pfeiffer_adapter.py
prefix_tuning
¶
Prefix Tuning module (parameter-efficient fine-tuning, T2 PEFT).
Wraps a frozen attention layer with a trainable prefix that gets
prepended to K and V at every forward pass. The prefix lives in a
small latent space (prefix_small) and is projected into the K/V
dimensions by two reparameterization MLPs - that's the "reparameterized"
Prefix Tuning from Li & Liang 2021, which stabilises training versus
directly learning the K/V prefix.
Multi-backend: MHA / FlashAttention / MultiLatentAttention
all support prefix_kv injection (any base that satisfies the
:class:llm.core.attn.base.PrefixCapableAttention Protocol). The
wrapper freezes the base attention and only prefix_small + the two
reparameterization MLPs receive gradients. After training,
:func:fold_reparameterization collapses the MLPs into static
prefix_k / prefix_v buffers for inference (one fewer matmul
per step, no trainable params at serve time, no risk of
training-mode behaviour leaking into deployment).
Reference: Li & Liang, 2021 - Prefix-Tuning: Optimizing Continuous Prompts for Generation, arXiv:2101.00190.
PrefixTuningAttention
¶
Bases: Module
Wrap a frozen attention base with trainable prefix K/V.
The base must satisfy the :class:llm.core.attn.base.PrefixCapableAttention
Protocol — i.e. accept a prefix_kv kwarg in its forward.
MultiHeadAttention (the original reference impl),
FlashAttention, and MultiLatentAttention all qualify.
The trainable parameters are:
prefix_small:(prefix_len, reparam_hidden)- small latent prefix. Lower-rank than the full K/V dimension so the search space is bounded._reparam_k/_reparam_v:nn.Linear(reparam_hidden, kv_dim)MLPs that project the small prefix into the K and V spaces.
Forward computes prefix K/V via the reparam MLPs (or reads the
static buffers if :func:fold_reparameterization has been called),
expands to [B, num_kv_heads, prefix_len, head_dim], and dispatches
to base_attn(x, prefix_kv=...). The base attention is frozen at
construction so only prefix parameters receive gradients.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
base_attn
|
PrefixCapableAttention
|
The frozen attention layer to wrap. Must satisfy
:class: |
必需 |
prefix_len
|
int
|
Number of prefix tokens to prepend to each layer's K and V. Typical values: 10-200. |
必需 |
reparam_hidden
|
int | None
|
Width of the reparam MLP's hidden dim. Defaults
to |
None
|
源代码位于: src/llm/core/prefix_tuning.py
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | |
forward
¶
Dispatch to the base MHA with the prefix K/V prepended.
Forwards every keyword argument (attn_mask, is_causal,
kv_cache, use_cache, batch_indices, start_pos,
paged_kv_cache, layer_idx) to the base MHA. Any caller-
supplied prefix_kv is silently overridden - the wrapper owns
prefix construction.
源代码位于: src/llm/core/prefix_tuning.py
apply_prefix_tuning
¶
Wrap every matching MultiHeadAttention in model with prefix tuning.
Mirrors :func:llm.core.lora.apply_lora and
:func:llm.core.adalora.apply_adalora so swapping LoRA → AdaLoRA →
Prefix Tuning in user code is a one-import change.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
model
|
Module
|
The model to adapt. Modified in-place. |
必需 |
prefix_len
|
int
|
Number of prefix tokens per attention layer. |
必需 |
reparam_hidden
|
int | None
|
Hidden dim of the reparam MLP. |
None
|
target_modules
|
list[str] | None
|
List of module-name substring patterns. If
|
None
|
返回:
| 类型 | 描述 |
|---|---|
Module
|
The same model, modified in-place. |
源代码位于: src/llm/core/prefix_tuning.py
get_prefix_parameters
¶
Yield every trainable prefix parameter (prefix_small + reparam MLPs).
Trainers pass this to the optimizer so only the prefix path is updated - the base MHA weights stay frozen. Yields 5 parameters per wrapped attention:
prefix_small_reparam_k.weight,_reparam_k.bias_reparam_v.weight,_reparam_v.bias
A wrapper that has been through :func:fold_reparameterization has
HAD these deleted (replaced by the static prefix_k/prefix_v
buffers) and yields nothing — the PEFT registry's get_parameters
for prefix_tuning feeds :func:llm.core.peft.checkpoint.save_peft,
which must not crash with AttributeError on a folded-and-share
workflow (RIL ISS-209).
源代码位于: src/llm/core/prefix_tuning.py
fold_reparameterization
¶
Collapse reparam MLPs into static prefix buffers for inference.
After fold:
prefix_small,_reparam_k,_reparam_vare removed from the wrapper (so the optimizer no longer references them and the model state_dict stops carrying them).prefix_k,prefix_vare registered as buffers with the final per-layer K/V values. They are not trainable.- Forward path skips the reparam MLPs and reads the buffers directly.
Idempotent: calling on an already-folded wrapper is a no-op (the existing buffers are preserved exactly).
Works on either a top-level model (walks every wrapper) or a single
:class:PrefixTuningAttention directly. Models with no prefix
wrappers are left untouched.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
model_or_attn
|
Module
|
A model containing wrapped attention modules, or
a single :class: |
必需 |
返回:
| 类型 | 描述 |
|---|---|
Module
|
The same object, modified in-place. |
源代码位于: src/llm/core/prefix_tuning.py
Component Registry¶
registry
¶
Component registries backed by runtime.Registry.
set_attention_kv_cache_capability
¶
Record whether name supports KV cache.
Called from each attention implementation at import time, alongside
@register_attention. Validation in ModelConfig.check_consistency
raises if a model declares attn_impl that has no capability record.
源代码位于: src/llm/core/registry.py
attention_supports_kv_cache
¶
Return whether the registered attention impl supports KV cache.
Raises KeyError if the impl has not declared its capability — that is
a registration bug, not a user error. ModelConfig validates this at
config-load time.
源代码位于: src/llm/core/registry.py
ensure_peft_methods_registered
¶
Idempotently register built-in methods and load entry points.
Built-ins are registered before the entry-point load so a
plugin that claims a built-in name raises / is silently skipped —
the built-in is the source of truth. This matches the convention
in :func:llm.export.registry.ensure_exporters_registered and
:func:llm.generation.registry.ensure_backends_registered.