[fsdp] fix: Handle dict type for per_tensor_param in LoRA weight sync (#3712)

## Description

When `peft_config` is set and `base_sync_done` is `True`,
`per_tensor_param` is assigned directly from the `params` dict instead
of `params.items()`, causing `ValueError: too many values to unpack
(expected 2)` when passed to `get_named_tensor_buckets()` which expects
an iterator of `(name, tensor)` tuples.

This fix adds an `isinstance()` check to handle both dict and iterator
cases, maintaining backward compatibility while fixing SGLang rollout
with LoRA adapters.

**Fixes:** `ValueError` in `sglang_rollout.update_weights()` →
`get_named_tensor_buckets()`
**Related:** Multi-turn RL training with LoRA adapters on SGLang backend

---

### What does this PR do?

This PR fixes a type mismatch bug in `fsdp_workers.py` that occurs when
using LoRA adapters with SGLang backend. The issue manifests during
weight synchronization when FSDP workers attempt to pass parameters to
the bucket creation function.

**Root Cause:** Line 681 in `verl/workers/fsdp_workers.py` assigns
`params` dict directly to `per_tensor_param`, but downstream code at
line 1520 in `get_named_tensor_buckets()` expects an iterator of `(name,
tensor)` tuples for unpacking.

**Solution:** Add backward-compatible `isinstance()` check that converts
dict to `.items()` iterator when needed:
```python
per_tensor_param = params.items() if isinstance(params, dict) else params
This commit is contained in:
Pouria Mistani
2025-10-10 06:58:30 -07:00
committed by GitHub
parent e01376663b
commit d87602432c

View File

@ -678,7 +678,7 @@ class ActorRolloutRefWorker(Worker, DistProfilerExtension):
set_expandable_segments(False) set_expandable_segments(False)
if peft_config is not None and self.base_sync_done: if peft_config is not None and self.base_sync_done:
per_tensor_param = params per_tensor_param = params.items() if isinstance(params, dict) else params # Fixed: handle dict case
else: else:
device = get_device_id() # used when fsdp2 set cpu_offload_policy device = get_device_id() # used when fsdp2 set cpu_offload_policy
per_tensor_param = ( per_tensor_param = (