Skip to content

Commit 4ba90fe

Browse files
yueming-yuanclaude
andcommitted
Record the expert LoRA layout in checkpoint metadata
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1 parent bc020cb commit 4ba90fe

5 files changed

Lines changed: 10 additions & 3 deletions

File tree

‎miles/tinker/core/input_validation.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,13 @@ def validate_checkpoint_compatibility(meta: dict, record: ModelRecord, config: G
117117
"base_model": record.base_model,
118118
"lora_rank": record.lora_rank,
119119
"lora_alpha": record.lora_alpha,
120+
"experts_shared_outer_loras": config.experts_shared_outer_loras,
120121
"train_attn": config.trains_attn,
121122
"train_mlp": config.trains_mlp,
122123
"train_unembed": config.trains_unembed,
123124
}
125+
# Checkpoints written before the layout was recorded are all per-expert.
126+
meta = {"experts_shared_outer_loras": False, **meta}
124127
for key, value in expected.items():
125128
if meta[key] != value:
126129
raise UserInputError(

‎miles/tinker/core/types.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class GatewayConfig:
5757
max_samples_per_request: int = 64
5858
max_lora_rank: int = 32 # the slot capacity the server was built with (--lora-rank)
5959
lora_alpha: float | None = None # None: 2 * rank
60+
experts_shared_outer_loras: bool = False
6061
# what the server-wide adapter layout trains; create_model rejects deviations
6162
trains_attn: bool = True
6263
trains_mlp: bool = True

‎miles/tinker/core/utils.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ def build_checkpoint_metadata(record: ModelRecord, config: GatewayConfig) -> dic
3333
"base_model": record.base_model,
3434
"lora_rank": record.lora_rank,
3535
"lora_alpha": record.lora_alpha,
36+
"experts_shared_outer_loras": config.experts_shared_outer_loras,
3637
"train_attn": config.trains_attn,
3738
"train_mlp": config.trains_mlp,
3839
"train_unembed": config.trains_unembed,

‎serve_tinker.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ async def serve(args, *, disposer: Disposer):
5959
vocab_size=hf_config.vocab_size,
6060
max_tokens_per_datum=max_tokens_per_datum,
6161
lora_alpha=args.lora_alpha,
62+
experts_shared_outer_loras=args.experts_shared_outer_loras,
6263
max_lora_rank=args.lora_rank,
6364
trains_attn="attn" in args.tinker_lora_groups,
6465
trains_mlp="mlp" in args.tinker_lora_groups,

‎tests/fast/tinker/core/test_service.py‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -628,7 +628,8 @@ async def test_checkpoint_meta_stores_a_digest_not_the_credential(service):
628628
assert (info["train_attn"], info["train_mlp"], info["train_unembed"]) == (True, True, False)
629629

630630

631-
async def test_a_checkpoint_saved_under_other_settings_does_not_load(service):
631+
@pytest.mark.parametrize("field,value", [("lora_alpha", 99), ("experts_shared_outer_loras", True)])
632+
async def test_a_checkpoint_saved_under_other_settings_does_not_load(service, field, value):
632633
import json
633634
import os
634635

@@ -641,14 +642,14 @@ async def test_a_checkpoint_saved_under_other_settings_does_not_load(service):
641642
resolve_checkpoint_dir(service.config.checkpoint_root, model_id, "weights", "ck"), "META.json"
642643
)
643644
meta = json.loads(open(meta_path).read())
644-
meta["lora_alpha"] = meta["lora_alpha"] + 1 # the same tensors would be scaled differently
645+
meta[field] = value
645646
open(meta_path, "w").write(json.dumps(meta))
646647

647648
loaded = service.submit(
648649
"tenant", "load_state", {"model_id": model_id, "seq_id": 2, "path": path, "optimizer": True}
649650
)
650651
future = await await_settled(service, "tenant", loaded)
651-
assert (future.state, future.error_category) == (FAILED, "user") and "lora_alpha" in future.error
652+
assert (future.state, future.error_category) == (FAILED, "user") and field in future.error
652653
assert not service.backend.named("load_slot")[1:], "nothing may touch the slot on a mismatch"
653654

654655

0 commit comments

Comments
 (0)