5.9 KiB
Deep CFR v0 Status vs Legacy coolrl
This document tracks the Lost Cities Deep CFR functionality in this repository
against the legacy implementation in ../coolrl.
Implemented In This Repository
Traversal
Implemented:
- Recursive
traverse(state, traverser, iteration, depth)logic. - Terminal value handling.
- Traverser vs opponent node behavior.
- Advantage-network-driven policies during traversal.
- Regret matching over legal actions.
- Sampled action recursion with node-value calculation.
- Instantaneous regret collection at traverser nodes.
- Strategy-memory collection.
- Depth and node-budget cutoffs.
- Outcome-sampling epsilon.
- Sampled action probability correction.
- Optional sampled value clipping.
- Unsampled regret modes:
negative_node_valuezero
- Score-diff and rollout-based cutoff values.
- Random and safe-heuristic cutoff rollout policies.
- Deck-draw chance sampling with state restoration.
Important implementation note:
- The active training path now calls
deep_cfr/traversal.pyx. - The old Python recursive
deep_cfr/traverser.pypath has been removed from mainline code. - The rules engine (
game.pyx), encoding (encoding.pyx), regret-matching math (cfr_math.pyx), and Deep CFR tree-walking loop now have Cython implementations.
Training And Memory
Implemented:
- PyTorch advantage networks.
- PyTorch strategy network.
- Legal-mask-aware advantage loss.
- Masked strategy cross-entropy loss.
- Reservoir memory with capacity limits.
- Batch sampling.
- Legal masks stored with samples.
- Single-process traversal.
- Multiprocessing traversal worker batches.
- Worker result merge in the parent trainer process.
Encoding
Implemented information-state features:
- Phase flags.
- Current player.
- Encoded player.
- Deck ratio.
- Player hand slot features.
- Public expedition summaries for both players.
- Public discard summaries.
- Public card counts.
- Total score and score diff features.
- Turn ratio.
- Pending-discard one-hot.
- Legal action mask.
The encoding is still compact compared with the legacy feature set, but it now contains the key public board, discard, score, and legal-action information.
Runtime Operations
Implemented:
- Checkpoint save/load.
- Latest and per-iteration checkpoint files.
- Config stored in checkpoints and
config.json. - Strategy-net policy adapter.
- Evaluation against registered classic bots.
- Training CLI.
- Evaluation CLI.
- Traversal benchmark CLI.
- Local run files:
config.jsonmetrics.jsonlruntime_progress.jsontrain.log
- Traversal benchmark metrics.
- Self-play league snapshots.
- Self-play league opponent selection from stored snapshots.
- Safe-heuristic anchor opponent path.
- Weighted current/recent/older/anchor self-play league buckets.
- Safe-heuristic imitation pretraining.
- Policy-gradient fine-tuning.
- Single-vs-multiprocessing benchmark comparison.
Remaining Differences From Legacy coolrl
The main Deep CFR v0 gaps listed earlier are now implemented. Remaining differences are mostly experiment-system maturity and legacy-specific research extras.
Still smaller than legacy:
- Config is YAML-first and nested through Pydantic, but only one smoke preset
exists under
configs/deep_cfr/. - Multiprocessing exists, but it is intentionally simple:
- no progress callback per worker batch
- no hotspot timing profile
- Metrics logging exists, but no plotting/status command exists yet.
- Checkpoint artifacts are local only; W&B artifact integration is not added.
- Legacy visualization helpers are not ported.
These remaining items are not blockers for running and iterating on Deep CFR v0.
Performance-Critical Gap
This repository was split out to pursue much higher Lost Cities training
performance. From that perspective, the main remaining gap is not feature
parity with legacy ../coolrl; it is the traversal backend.
Current state:
GameStatemutation, legal-action generation, apply/undo, and cached scoring are implemented in Cython.- Information-state encoding and regret matching have Cython modules.
- Full Deep CFR traversal now runs through
traversal.pyx. - PyTorch policy inference and reservoir memory sample materialization still cross the Python boundary.
- Traversal is still recursive inside Cython. The Python recursion-limit guard is no longer the main execution path, but an explicit iterative scheduler is still a future optimization.
Recommended performance roadmap:
- Continue moving the traversal hot path away from Python object boundaries:
- C-level legal action enumeration
- C-level push/pop undo
- terminal, depth cutoff, and node-budget cutoff
- traverser/opponent node handling
- outcome sampling
- sampled action value correction
- instantaneous regret calculation
- strategy sample collection
- traversal stats collection
- Reduce Python boundary costs with batched memory writes.
- Add batched network inference for policy calls.
- Replace the recursive Cython DFS with an explicit Cython traversal scheduler.
- Run multiple traversal contexts concurrently so policy-needed states can be encoded and evaluated in batches.
Python iterative traversal is not the preferred performance path. It would remove Python recursion-limit risk, but it would keep most Python object and callback overhead in the hot loop. For performance, the next serious step is a Cython batched iterative traversal scheduler.
Suggested Next Steps
- Add batched memory writes from the Cython traversal engine.
- Add benchmark output for recursive Cython traversal vs batched iterative traversal once the scheduler exists.
- Add batched policy inference.
- Add an explicit Cython iterative traversal scheduler.
- Add a status/plot command that reads
metrics.jsonl. - Add worker progress logging and hotspot timing profile.
- Add W&B checkpoint artifacts after checkpoint quality is stable.