中文 | English
This project predicts CS2 Major Swiss stage results using ELO + Monte Carlo simulation + Valve's official Buchholz pairing rules.
Basically runs 100k Swiss round simulations, then brute-force searches through 10 million Pick'Em combinations to find the optimal prediction. Calculates team ratings based on historical match data.
v2.0 supports GPU acceleration: Dozens of times faster than v1.0's 16-core CPU (thanks to Tenzray's PR).
CSV file without header, 7 columns:
date,team1,score1,score2,team2,tournament,format
2025-11-21,Team A,2,1,Team B,Example Tournament,bo3
2025-11-20,Team C,16,14,Team D,Example League,bo1
date: YYYY-MM-DD formatteam1,team2: Team names (must match your SEEDED_TEAMS list in code)score1,score2: Match scorestournament: Tournament name (just for reference, write whatever)format:bo1,bo3, orbo5
CSV with header, HLTV ratings:
team,Maps,KD_diff,KD,Rating
Team A,120,+250,1.08,1.09
Team B,95,+180,1.06,1.07Only team and Rating columns matter. Grab latest ratings from HLTV.org if you want more accurate initial values.
pip install -r requirements.txtNote: For GPU acceleration, ensure you have CUDA installed. PyTorch will automatically use GPU if available.
Edit batchsize.yaml to adjust performance:
simulation:
num_simulations: 500 # Number of Monte Carlo simulations
performance:
eval_batch_size: 5000 # Adjust based on GPU memory
save_every: 1000000 # Checkpoint frequency
device:
use_gpu: true # true for GPU, false for CPU
gpu_id: 0 # GPU device ID (usually 0)Edit cs2_gen_preresult.py (current team names are just examples, change based on actual situation):
SEEDED_TEAMS = [
"FURIA", # Seed 1
"Vitality", # Seed 2
# ... 16 teams total, in seed order
]Just fill in seed rankings. Round 1 matchups auto-generate based on Valve rules (1v9, 2v10, 3v11, ...).
Program will show generated schedule for confirmation before running.
Step 1: Generate simulation data
python cs2_gen_preresult.pyThis creates output/intermediate_sim_data.json with 100k Swiss round simulations.
Step 2: GPU-accelerated Pick'Em optimization
python cs2_gen_final.pyStandard ELO with some improvements:
- Time decay (50-day half-life) - old matches weighted less
- Format weights: BO1=1.0, BO3=1.2, BO5=1.5
- Adaptive K-factor: starts at K=50 for quick adjustment, drops to K=30 after 30 matches
- Blends HLTV ratings with historical data (more history = less HLTV weight)
- Form variance: BO1 ±60, BO3 ±35, BO5 ±20 ELO random fluctuation per match (simulates upsets)
Win probability: P = 1 / (1 + 10^((rating2-rating1)/400))
Based on Valve's official rules
Brute-force enumerates all valid combinations:
- 2 teams with 3-0
- 6 teams with 3-1 or 3-2
- 2 teams with 0-3
Total: C(16,6) × C(10,2) × C(8,2) = 10,090,080 combinations
Selects the combo with highest success rate (at least 5 hits) from 100k simulations.
v2.0 GPU Optimization: Uses PyTorch tensors and matrix multiplication for batch evaluation, achieving significant speedup on NVIDIA GPUs.
Generated files:
output/final_prediction.json- Full results with best Pick'Em combinationoutput/optimized_report.txt- Human-readable recommendationsoutput/intermediate_sim_data.json- Cached simulation data (from step 1)gpu_checkpoint.json- Auto-saved progress (can resume if interrupted)
Notes:
- Each team needs at least 10 historical matches for reliable predictions
- Delete
gpu_checkpoint.jsonif you want to restart optimization from scratch - The two-step design allows you to rerun step 2 with different settings without regenerating simulations
- CPU version
cs2_swiss_predictor_cpu.pyavailable for users without GPU
Finally, this project is inspired by claabs/cs-buchholz-simulator