F1-Strategy is an open-weight model from Haokun Wang, released under MIT License. Its published files total 12.9 MB.
Watch a race unfold, explore pit strategy, and reproduce the model training behind it. Pitwall combines an animated Formula 1 race center with a historical race simulator and an end-to-end machine-learning pipeline. Race Center opens with a recorded race.
Model Card
By Haokun Wang, published under mit, revision e77a89ba37fe.
Watch a race unfold, explore pit strategy, and reproduce the model training behind it. Pitwall combines an animated Formula 1 race center with a historical race simulator and an end-to-end machine-learning pipeline. Race Center opens with a recorded race. Cars follow actual OpenF1 position samples around a recorded circuit trace, with smooth interpolation between samples. and selected-car views. gear, throttle, brake, completed-lap sectors, weather, and race-control messages. rejoin position from current gaps, and an undercut watch for nearby rivals. pretraining and fine-tuning results. Historical replay is free, with OpenF1 coverage from 2023 onwards. The first load of a race downloads and…
Read Haokun Wang's full model card
Pitwall AI
Watch a race unfold, explore pit strategy, and reproduce the model training behind it. Pitwall combines an animated Formula 1 race center with a historical race simulator and an end-to-end machine-learning pipeline.
Open the live demo · Training results · Race Center guide
Explore the race
Race Center opens with a recorded race. Cars follow actual OpenF1 position samples around a recorded circuit trace, with smooth interpolation between samples.
- Track position: follow any driver, toggle labels, and switch between full-circuit and selected-car views.
- Race panels: classification and gaps, tyre compounds and stint history, speed, gear, throttle, brake, completed-lap sectors, weather, and race-control messages.
- Pit window: measured-history pit-lane time, estimated race-time loss, projected rejoin position from current gaps, and an undercut watch for nearby rivals.
- Playback: pause, seek, restart, and replay at 1×–60×. Timing follows the replay cursor.
- Strategy Lab: compare the baked model experiments and read the latest published pretraining and fine-tuning results.
Historical replay is free, with OpenF1 coverage from 2023 onwards. The first load of a race downloads and caches its GPS and telemetry, which can take a minute or more. Positions are approximate; missing or stale data stays unavailable.
The Live tab checks the current session, refreshes every 15 seconds and uses a 20-second playback buffer. It shows a waiting screen between sessions. Current live data requires an OpenF1 subscription and server credentials; the public replay needs neither. See connection setup.
Latest training result
The October 16 run used 120,935 lap records across 109 events, including 17 completed 2026 races acquired through OpenF1. A separate pit-time model fitted 1,815 routine measured stops from earlier races. The policy lifecycle covers supporting-model pretraining and adaptation, simulator validation, behavioral cloning, four-frame PPO pretraining, and recent-event fine-tuning.
| Held-out policy | Mean position | Mean race time (s) | Mean pit stops |
|---|---|---|---|
| Source PPO | 8.575 | 5983.33 | 1.60 |
| Fine-tuned PPO | 8.550 | 5986.12 | 1.82 |
| Dynamic-programming benchmark | 8.400 | 5972.31 | 1.00 |
The new PPO candidate is not promoted. It trailed dynamic programming by 13.73 seconds on the held-out event-weighted comparison. Evaluation used 40 paired episodes across three eligible events and one training seed. Both simulator gates passed the required Spearman rho ≥ 0.7 (0.828 and 0.821). The independent measured pit-time model is available to Race Center regardless of policy promotion.
Read the model card for splits, uncertainty, supporting-model metrics and limitations, and the algorithm decision for the research behind the method. The race-center strategy desk is a labelled nominal dry-race DP reference, separate from the calibrated evaluation benchmark.
Run locally
Use Python 3.11 and uv.
git clone https://github.com/whk-irl/F1_Strategy.git
cd F1_Strategy
uv sync --python 3.11 --extra dev
uv run streamlit run services/frontend/app.py
Open http://localhost:8501. Race Center fetches historical data on first use.
Strategy Lab includes baked models and 2022–2025 lap data, so training is optional
for exploring those experiments. The published model card and chart also ship with
the app; full checkpoints and MLflow runs remain local generated artifacts.
For live access, set OPENF1_TOKEN on the server, or OPENF1_USERNAME and
OPENF1_PASSWORD for automatic token renewal. .env.example lists optional settings.
Keep credentials in environment variables or the hosting provider's secret store.
Retrain end to end
uv run python -m services.ingestion.acquire --years 2026 --provider auto
uv run python scripts/acquire_pit_history.py --years 2023,2024,2025,2026
uv run python -m ml.pipelines.pit_time
uv run python -m ml.pipelines.train --config configs/training.pit-time.json
flowchart LR
A[FastF1 / OpenF1] --> B[Bronze → Silver → Gold]
A --> P[Measured pit timing → venue forecast]
B --> C[World-model pretraining and adaptation]
C --> D[Simulator fidelity gates]
P --> D
D --> E[Behavioral pretraining]
E --> F[History-aware PPO]
F --> G[Recent-event fine-tuning]
G --> H[Held-out evaluation against DP]
H --> I[Versioned artifacts and MLflow report]
Acquisition is resumable and records source checksums. Features are rebuilt causally; event splits are chronological, with validation for checkpoint selection and separate final test events. Policy learning starts only after both simulator gates pass.
The local profile budgets 200,000 PPO source steps and 100,000 fine-tuning steps.
It writes checkpoints, normalization statistics, split membership, metrics and
provenance under runs/. Use --resume to verify completed stages of an unchanged
run. Choose a new output_dir after changing source, data or configuration; the
saved October 16 run is tied to the source fingerprint in its report.
See the training guide for configuration, artifacts and inference. The 96-input staged candidate has a dedicated loader and does not overwrite the legacy 21-input models.
Validation and scope
uv run ruff check .
uv run ruff format --check .
uv run mypy services/ ml/
uv run pytest
The October 16 update passed 167 tests with 89.14% configured coverage, plus Ruff and mypy checks. Replay controls and desktop/mobile layouts were checked in the browser. Authenticated active-session timing still requires verification during a race.
This is an independent research project. Opponents follow recorded trajectories; they do not react to the policy. The trained candidate covers dry races without red flags and does not model tyre inventory. Results do not establish real-race superiority.
The repository also contains cloud-agnostic storage, serving and infrastructure scaffolding. Deployment instructions describe the existing Streamlit Community Cloud app. See architecture and scope for the wider project.
License
The project declares the MIT license. Race data is supplied by FastF1 and OpenF1. This project is unofficial and is not affiliated with Formula 1, the FIA, or any team.
Identity and Version
- Repository
- hkstormstout/F1-Strategy
- Publisher
- Haokun Wang
- Task
- Not stated by the source
- Modality
- Other
- Library
- Not stated by the source
- Parameters
- Not stated by the source
- Languages
- Not stated by the source
- Revision
- e77a89ba37fefbca6610a98e02448cc710cd64f2
- First published
- 2026-10-17
- Last updated
- 2026-10-17
Files and Weights
174 files, 12.9 MB in total. The weights are 2 files totalling 5.4 MB in pt.
Every file
| File | Type | Size | SHA-256 |
|---|---|---|---|
| models_baked/tire_patch_tst/model.pt | Weights | 2.6 MB | f779ab89447c |
| models_baked/tire_tcn_gru/model.pt | Weights | 2.8 MB | 9dffc305dc40 |
| .devcontainer/devcontainer.json | Configuration | 1.1 KB | — |
| .github/workflows/ci.yml | Configuration | 2.6 KB | — |
| .github/workflows/train-cloud.yml | Configuration | 5.7 KB | — |
| .pre-commit-config.yaml | Configuration | 2.6 KB | — |
| configs/training.local.json | Configuration | 750 B | — |
| configs/training.pit-time.json | Configuration | 765 B | — |
| docker-compose.yml | Configuration | 3.7 KB | — |
| infra/argo/workflows/train-safety-car.yaml | Configuration | 1.8 KB | — |
| infra/argo/workflows/train-strategy-policy.yaml | Configuration | 2.4 KB | — |
| infra/argo/workflows/train-tire-degradation.yaml | Configuration | 1.9 KB | — |
| ml/__init__.py | Configuration | — | |
| ml/features/__init__.py | Configuration | 312 B | — |
| ml/features/data_sources.py | Configuration | 277 B | — |
| ml/features/definitions.py | Configuration | 3.9 KB | — |
| ml/features/entities.py | Configuration | 269 B | — |
| ml/features/feature_store.yaml | Configuration | 372 B | — |
| ml/features/feature_views.py | Configuration | 443 B | — |
| ml/models/__init__.py | Configuration | — | |
| ml/models/_loader.py | Configuration | 3.5 KB | — |
| ml/models/safety_car/__init__.py | Configuration | — | |
| ml/models/safety_car/predict.py | Configuration | 3.1 KB | — |
| ml/models/safety_car/train.py | Configuration | 9.5 KB | — |
| ml/models/strategy_policy/__init__.py | Configuration | — | |
| ml/models/strategy_policy/per_buffer.py | Configuration | 9.7 KB | — |
| ml/models/strategy_policy/predict.py | Configuration | 5.5 KB | — |
| ml/models/strategy_policy/predict_dqn.py | Configuration | 6.2 KB | — |
| ml/models/strategy_policy/predict_staged.py | Configuration | 3.0 KB | — |
| ml/models/strategy_policy/train.py | Configuration | 14.2 KB | — |
| ml/models/strategy_policy/train_dqn.py | Configuration | 19.6 KB | — |
| ml/models/tire_degradation/__init__.py | Configuration | — | |
| ml/models/tire_degradation/model_patch_tst.py | Configuration | 4.4 KB | — |
| ml/models/tire_degradation/model_tcn_gru.py | Configuration | 6.3 KB | — |
| ml/models/tire_degradation/predict.py | Configuration | 3.4 KB | — |
| ml/models/tire_degradation/predict_sequence.py | Configuration | 12.2 KB | — |
| ml/models/tire_degradation/sequence_dataset.py | Configuration | 11.0 KB | — |
| ml/models/tire_degradation/train.py | Configuration | 7.2 KB | — |
| ml/models/tire_degradation/train_sequence.py | Configuration | 14.4 KB | — |
| ml/models/tire_degradation/wrapper.py | Configuration | 2.6 KB | — |
| ml/pipelines/__init__.py | Configuration | — | |
| ml/pipelines/config.py | Configuration | 2.9 KB | — |
| ml/pipelines/data.py | Configuration | 6.0 KB | — |
| ml/pipelines/pit_time.py | Configuration | 10.1 KB | — |
| ml/pipelines/policy.py | Configuration | 18.5 KB | — |
| ml/pipelines/report.py | Configuration | 3.4 KB | — |
| ml/pipelines/train.py | Configuration | 15.4 KB | — |
| ml/pipelines/world_models.py | Configuration | 10.5 KB | — |
| models_baked/manifest.json | Configuration | 1.4 KB | — |
| models_baked/pit_time.json | Configuration | 6.4 KB | — |
| models_baked/sc/conda.yaml | Configuration | 7.6 KB | — |
| models_baked/sc/python_env.yaml | Configuration | 114 B | — |
| models_baked/tire/conda.yaml | Configuration | 7.6 KB | — |
| models_baked/tire/python_env.yaml | Configuration | 114 B | — |
| models_baked/tire_patch_tst/config.json | Configuration | 176 B | — |
| models_baked/tire_patch_tst/norm_stats.json | Configuration | 546 B | — |
| models_baked/tire_tcn_gru/config.json | Configuration | 173 B | — |
| models_baked/tire_tcn_gru/norm_stats.json | Configuration | 546 B | — |
| scripts/acquire_pit_history.py | Configuration | 2.9 KB | — |
| scripts/export_for_deploy.py | Configuration | 3.1 KB | — |
| scripts/upload_gold_to_s3.py | Configuration | 2.4 KB | — |
| scripts/validate_tire_models.py | Configuration | 6.1 KB | — |
| services/__init__.py | Configuration | — | |
| services/api/__init__.py | Configuration | — | |
| services/frontend/__init__.py | Configuration | — | |
| services/frontend/app.py | Configuration | 1.5 KB | — |
| services/frontend/race_center.py | Configuration | 6.7 KB | — |
| services/frontend/strategy_lab.py | Configuration | 54.8 KB | — |
| services/ingestion/__init__.py | Configuration | — | |
| services/ingestion/acquire.py | Configuration | 10.9 KB | — |
| services/ingestion/config.py | Configuration | 4.0 KB | — |
| services/ingestion/fastf1_client.py | Configuration | 4.0 KB | — |
| services/ingestion/openf1_archive.py | Configuration | 10.2 KB | — |
| services/ingestion/pipeline.py | Configuration | 8.1 KB | — |
| services/ingestion/schemas/__init__.py | Configuration | 260 B | — |
| services/ingestion/schemas/bronze.py | Configuration | 2.2 KB | — |
| services/ingestion/schemas/gold.py | Configuration | 2.6 KB | — |
| services/ingestion/schemas/silver.py | Configuration | 2.7 KB | — |
| services/ingestion/storage.py | Configuration | 5.6 KB | — |
| services/ingestion/transforms.py | Configuration | 10.5 KB | — |
| services/live/__init__.py | Configuration | 52 B | — |
| services/live/obs_builder.py | Configuration | 8.9 KB | — |
| services/live/openf1_client.py | Configuration | 7.6 KB | — |
| services/live/race_data.py | Configuration | 19.5 KB | — |
| services/simulator/__init__.py | Configuration | 89 B | — |
| services/simulator/circuits.py | Configuration | 1.6 KB | — |
| services/simulator/env.py | Configuration | 35.8 KB | — |
| services/simulator/lap_simulator.py | Configuration | 5.4 KB | — |
| services/simulator/pit_time.py | Configuration | 1.4 KB | — |
| services/simulator/tyre_calibration.py | Configuration | 7.2 KB | — |
| services/simulator/validator.py | Configuration | 6.8 KB | — |
| test_policy.py | Configuration | 3.7 KB | — |
| tests/__init__.py | Configuration | — | |
| tests/conftest.py | Configuration | 4.1 KB | — |
| tests/data_quality/__init__.py | Configuration | — | |
| tests/data_quality/test_contracts.py | Configuration | 4.4 KB | — |
| tests/integration/__init__.py | Configuration | — | |
| tests/unit/__init__.py | Configuration | — | |
| tests/unit/ingestion/__init__.py | Configuration | — | |
| tests/unit/ingestion/test_acquisition.py | Configuration | 7.3 KB | — |
| tests/unit/ingestion/test_schemas.py | Configuration | 2.9 KB | — |
| tests/unit/ingestion/test_storage.py | Configuration | 4.6 KB | — |
| tests/unit/ingestion/test_transforms.py | Configuration | 6.0 KB | — |
| tests/unit/live/__init__.py | Configuration | — | |
| tests/unit/live/test_obs_builder.py | Configuration | 11.2 KB | — |
| tests/unit/test_pit_time.py | Configuration | 1.7 KB | — |
| tests/unit/test_race_data.py | Configuration | 10.9 KB | — |
| tests/unit/test_staged_pipeline.py | Configuration | 6.7 KB | — |
| tests/unit/test_training_lifecycle.py | Configuration | 4.5 KB | — |
| tests/unit/tire/__init__.py | Configuration | — | |
| tests/unit/tire/test_sequence_models.py | Configuration | 13.9 KB | — |
| ADR-0001.md | Documentation | 1.8 KB | — |
| CLAUDE.md | Documentation | 8.1 KB | — |
| README.md | Documentation | 7.5 KB | — |
| docs/architecture.md | Documentation | 5.5 KB | — |
| docs/decisions/0001-cloud-agnostic-mlops.md | Documentation | 1.5 KB | — |
| docs/decisions/0002-aws-s3-gpu-training.md | Documentation | 3.1 KB | — |
| docs/decisions/0003-dqn-per-strategy-policy.md | Documentation | 5.1 KB | — |
| docs/decisions/0004-sequence-tire-models.md | Documentation | 4.4 KB | — |
| docs/decisions/0005-staged-policy-training.md | Documentation | 5.1 KB | — |
| docs/decisions/0006-recorded-race-center.md | Documentation | 2.3 KB | — |
| docs/guides/aws-setup.md | Documentation | 7.6 KB | — |
| docs/guides/deployment.md | Documentation | 2.9 KB | — |
| docs/guides/race-center.md | Documentation | 6.3 KB | — |
| docs/guides/staged-training.md | Documentation | 6.8 KB | — |
| docs/model-cards/2026-10-15-retraining.md | Documentation | 5.2 KB | — |
| docs/model-cards/2026-10-16-pit-time-retraining.md | Documentation | 4.9 KB | — |
| docs/scope.md | Documentation | 1.9 KB | — |
| scope.md | Documentation | 1.9 KB | — |
| tests/fixtures/README.md | Documentation | 612 B | — |
| .streamlit/config.toml | Other | 271 B | — |
| Dockerfile | Other | 1.6 KB | — |
| Makefile | Other | 10.3 KB | — |
| data/gold_2022_2025.parquet | Other | 2.6 MB | a29c62ecbdac |
| data/gold_2024.parquet | Other | 965.8 KB | a8952d079716 |
| docs/assets/pit-time-training-summary.png | Other | 73.4 KB | — |
| docs/assets/race-center.png | Other | 125.5 KB | 0ee637fa8f13 |
| docs/assets/training-summary.png | Other | 186.7 KB | 5df7f43b77b8 |
| infra/docker/postgres-init.sql | Other | 213 B | — |
| infra/terraform/aws/backend.tf.example | Other | 504 B | — |
| infra/terraform/aws/bootstrap/main.tf | Other | 3.9 KB | — |
| infra/terraform/aws/ecr.tf | Other | 1.7 KB | — |
| infra/terraform/aws/eks.tf | Other | 4.6 KB | — |
| infra/terraform/aws/iam.tf | Other | 4.2 KB | — |
| infra/terraform/aws/main.tf | Other | 1.5 KB | — |
| infra/terraform/aws/outputs.tf | Other | 1.6 KB | — |
| infra/terraform/aws/s3.tf | Other | 1.9 KB | — |
| infra/terraform/aws/terraform.tfvars.example | Other | 620 B | — |
| infra/terraform/aws/variables.tf | Other | 2.3 KB | — |
| infra/terraform/aws/vpc.tf | Other | 1.2 KB | — |
| ml/models/safety_car/Dockerfile | Other | 748 B | — |
| ml/models/strategy_policy/Dockerfile | Other | 1.4 KB | — |
| ml/models/tire_degradation/Dockerfile | Other | 1.2 KB | — |
| models_baked/dqn_policy/model/policy.zip | Other | 651.3 KB | 78df98b94954 |
| models_baked/policy/model/policy.zip | Other | 964.6 KB | d7affdfdb6fb |
| models_baked/sc/MLmodel | Other | 787 B | — |
| models_baked/sc/model.pkl | Other | 6.9 KB | 8a9cb535de7f |
| models_baked/sc/registered_model_meta | Other | 39 B | — |
| models_baked/sc/requirements.txt | Other | 6.4 KB | — |
| models_baked/tire/MLmodel | Other | 788 B | — |
| models_baked/tire/model.pkl | Other | 181.1 KB | f6e87fcba4e9 |
| models_baked/tire/registered_model_meta | Other | 39 B | — |
| models_baked/tire/requirements.txt | Other | 6.4 KB | — |
| pyproject.toml | Other | 5.1 KB | — |
| requirements.txt | Other | 670 B | — |
| services/frontend/race_center_component/app.js | Other | 28.6 KB | — |
| services/frontend/race_center_component/index.html | Other | 10.7 KB | — |
| services/frontend/race_center_component/style.css | Other | 21.4 KB | — |
| uv.lock | Other | 837.6 KB | — |
| .dockerignore | Repository | 295 B | — |
| .env.example | Repository | 3.0 KB | — |
| .gitattributes | Repository | 1.7 KB | — |
| .gitignore | Repository | 6.0 KB | — |
| ml/notebooks/.gitkeep | Repository | — |
License and Download
- License
- mit
- Access
- Open weights, no gate
- Download size
- 5.4 MB
Released by Haokun Wang through its official repository on Hugging Face. Read the license.
Memory Requirements
| Precision | Weights in memory |
|---|---|
| As published | 5.4 MB |
Weights only, from the published parameter count; the key-value cache and runtime add to this.
Questions About F1-Strategy
Can I use F1-Strategy commercially?
Yes. F1-Strategy is released under MIT License. The MIT License is a short permissive license. It permits commercial use, modification and redistribution, provided the copyright notice and permission notice are included.