Aswinesag/f1-telemetry-anomaly-engine

GitHub: Aswinesag/f1-telemetry-anomaly-engine

一个基于 Kafka、FastAPI 和 PyTorch 的实时 F1 遥测监控与异常检测系统,通过流式架构实现物理特征工程和异步 ML 推理,并在 pitwall 风格的 Next.js 仪表盘上可视化车辆健康状态。

Stars: 0 | Forks: 0

# F1 遥测异常引擎 面向生产环境的遥测流水线,用于模拟高频一级方程式(F1)传感器数据流,推导基于物理的热力学特征,执行异步 ML 推理,并在类似维修区墙(pitwall)的仪表盘上可视化异常特征。 当前的实现基于解耦的流式架构: - **Kafka** 负责传输回放的遥测数据帧。 - **FastAPI** 托管健康/就绪状态端点、数据摄取以及 WebSocket 流。 - **InferenceWorker** 在后台执行非阻塞的模型推理。 - **Redis** 存储最新处理的推理结果,以实现低延迟的仪表盘读取。 - **PostgreSQL** 通过 SQLAlchemy 2.0 异步会话持久化遥测快照和异常分数。 - **Next.js** 在端口 `8502` 上渲染维修区墙(pitwall)仪表盘。 # **演示** https://github.com/user-attachments/assets/ed0b3696-9afb-4ec1-83f8-ffb566635091 ## 系统概述 ``` FastF1 / CSV replay | v Telemetry replay producer | v Kafka topic: f1-telemetry-bus | v FastAPI inference-api | +--> async Kafka consumer +--> bounded InferenceWorker queue +--> vectorized PhysicsEngine feature generation +--> PyTorch virtual thermal sensor +--> PyTorch anomaly autoencoder +--> Redis latest-result cache +--> PostgreSQL telemetry_snapshots table | v WebSocket / HTTP latest telemetry | v Next.js pitwall dashboard ``` ## 实现状态 ### 已完成 - 用于 Kafka、ZooKeeper、Redis、PostgreSQL、FastAPI、仪表盘及可选回放的 Docker Compose 编排。 - 具备生命周期管理的 Kafka 消费者、Redis 客户端、DB 引擎和推理 worker 的异步 FastAPI 服务。 - `/health`、`/ready`、`/telemetry`、`/telemetry/latest` 和 `/ws/telemetry` 端点。 - `src/engine/physics.py` 中无状态、可复用的向量化物理引擎。 - 使用 1D CNN + 双向 LSTM 的 PyTorch 虚拟传感器模型。 - 用于异常隔离的 PyTorch 残差自编码器。 - 用于遥测快照的 SQLAlchemy 2.0 异步持久化模型。 - 由 Redis 支持的最新推理结果,用于仪表盘数据填充和 WebSocket 更新。 - Next.js + Tailwind + Recharts 维修区墙(pitwall)仪表盘。 - Docker 运行时依赖拆分: - 用于 API 推理的 `requirements-api.txt`。 - 用于 Kafka 回放的 `requirements-replay.txt`。 - 用于完整本地训练/原型工具的 `requirements.txt`。 - 主机 API 端口移至 `18080`,因为 Windows 通常会保留端口 `8000`。 ### 当前运行端口 | 组件 | 主机 URL / 端口 | 容器端口 | |---|---:|---:| | 仪表盘 | `http://localhost:8502` | `8502` | | 推理 API | `http://localhost:18080` | `8000` | | Kafka 外部监听器 | `localhost:9092` | `9092` | | PostgreSQL | `localhost:5432` | `5432` | | Redis | `localhost:6379` | `6379` | | ZooKeeper | `localhost:2181` | `2181` | ## 仓库结构 ``` . ├── api/ │ ├── main.py # FastAPI app, lifespan, routes, Kafka consumer task │ ├── schemas.py # Pydantic request/response schemas │ ├── worker.py # Async inference worker, Redis latest cache, DB persistence │ └── database/ │ └── models.py # SQLAlchemy 2.0 async engine/session and TelemetrySnapshot model ├── config/ │ └── config.yaml # Sampling rate, feature columns, model hyperparameters, threshold config ├── data/ │ ├── virtual_sensor.pt # Trained virtual thermal sensor checkpoint │ ├── isolation_engine.pt # Trained anomaly autoencoder checkpoint │ └── raw_samples/ # Replay CSV generated by training ├── f1-dashboard/ │ └── app/ │ ├── Dashboard.tsx # Pitwall dashboard UI │ └── page.tsx # Next.js route entry ├── src/ │ ├── engine/ │ │ └── physics.py # Vectorized thermodynamic feature engine │ ├── models/ │ │ ├── virtual_sensor.py # 1D CNN + BiLSTM virtual sensor │ │ └── autoencoder.py # Residual reconstruction anomaly detector │ └── pipeline/ │ ├── etl_processor.py # FastF1 extraction, alignment, scaling │ ├── ingestion.py # Kafka producer/consumer helpers │ └── replay_simulation.py # CSV-to-Kafka replay simulator ├── tests/ │ └── test_physics.py # Physics engine tests ├── docker-compose.yml ├── Dockerfile # Next.js dashboard image ├── Dockerfile.api # FastAPI inference image ├── Dockerfile.replay # Telemetry replay image ├── requirements.txt # Full local training/prototype stack ├── requirements-api.txt # Runtime API dependencies with CPU Torch ├── requirements-replay.txt # Lightweight replay dependencies └── train.py # End-to-end training pipeline ``` ## 技术栈 ### 后端 / 流处理 - **FastAPI** 用于异步 HTTP 和 WebSocket API。 - **Uvicorn** ASGI 运行时。 - **aiokafka** 用于 API 内部的异步 Kafka 消费。 - **kafka-python** 用于回放生产者兼容性。 - **Redis asyncio 客户端** 用于低延迟的最新结果存储。 - **SQLAlchemy 2.0 异步** 搭配 **asyncpg** 用于 PostgreSQL 持久化。 - **Pydantic** 用于类型化的遥测请求契约。 ### 机器学习 / 数据 - **PyTorch** 用于虚拟传感器和异常自编码器。 - **NumPy / Pandas** 用于向量化特征生成。 - **scikit-learn MinMaxScaler** 与虚拟传感器 checkpoint 存储在一起。 - **FastF1** 用于训练流水线中的历史 F1 遥测数据提取。 - **SciPy CubicSpline** 用于训练期间的遥测重采样/对齐。 ### 前端 - **Next.js 16** 搭配 React。 - **Tailwind CSS 4** 用于样式设计。 - **Recharts** 用于响应式遥测图表。 - **lucide-react** 用于仪表盘图标。 ### 基础设施 - **Docker Compose** 用于本地多服务编排。 - **Confluent Kafka + ZooKeeper** 用于流传输。 - **PostgreSQL 16 Alpine** 用于遥测快照存储。 - **Redis 7 Alpine** 用于最新推理缓存。 - API 镜像中使用 **仅支持 CPU 的 PyTorch wheel**,以避免庞大的 CUDA 下载。 ## 核心架构决策 ### 1. 解耦的异步推理 API 不会直接在路由处理器中运行繁重的推理。传入的 Kafka 消息和可选的 HTTP 遥测 POST 请求会被推送到有界的 `asyncio.Queue` 中。`InferenceWorker` 消费队列,保持滚动序列窗口,在后台任务中运行模型推理,并将结果写入 Redis/PostgreSQL。 这可以保持: - HTTP 端点的响应能力。 - WebSocket 流与模型执行相互独立。 - Kafka 摄取与仪表盘读取相互隔离。 - 持久化失败被限制在 worker 日志记录中,而不会导致 WebSocket 崩溃。 ### 2. Redis 作为最新状态缓存 仪表盘通常需要最新的遥测状态,而不是完整的数据库查询。worker 将最新的推理 payload 写入: ``` telemetry:inference:latest ``` 仪表盘从以下位置填充数据: ``` GET /telemetry/latest ``` 然后它从以下位置接收实时更新: ``` ws://localhost:18080/ws/telemetry ``` ### 3. PostgreSQL 用于历史快照 每个处理过的推理结果都可以作为 `TelemetrySnapshot` 行进行持久化,其中包含: - 原始遥测快照。 - 构建的物理快照。 - 预测的热力学状态。 - 实际的合成制动温度目标。 - 异常分数。 - 后端模型阈值。 - 布尔值异常标志。 - 模型版本元数据。 ### 4. 共享的物理引擎 `src/engine/physics.py` 被特意设计为无状态的,并且可以被以下两者导入: - `train.py` / ETL 流水线。 - `api/worker.py` / 实时推理运行时。 这避免了由于重复的特征公式导致的训练与服务偏差。 ### 5. 运行时依赖拆分 原始的完整依赖文件对于运行时容器来说过于臃肿。该项目现在将依赖项拆分为: - `requirements.txt`:本地训练和完整实验。 - `requirements-api.txt`:带有仅支持 CPU Torch 的 API 推理运行时。 - `requirements-replay.txt`:仅用于回放生产者。 ## 物理特征工程 物理引擎使用向量化的 Pandas/NumPy 操作推导热力学和车辆动力学特征: - `Speed_ms` - `Delta_KE` - `Acceleration` - `Longitudinal_G` - `Aero_Drag_N` - `Aero_Downforce_N` - `Effective_Weight_N` - `Brake_Work_EMA` - `Convective_Cooling_Factor` - `Brake_Temp_Target` 所需的原始遥测列: ``` Speed, Brake ``` 配置的模型特征列: ``` raw_channels: - Speed - Throttle - Brake - RPM - nGear physics_engineered: - Delta_KE - Brake_Work_EMA - Acceleration - Longitudinal_G - Aero_Drag_N - Aero_Downforce_N - Effective_Weight_N - Convective_Cooling_Factor ``` ## ML 流水线 ### 虚拟热力学传感器 在 `src/models/virtual_sensor.py` 中实现。 模型结构: ``` Input sequence -> Conv1D feature extractor -> BatchNorm + ReLU + Dropout -> 2-layer bidirectional LSTM -> dense regressor head -> predicted brake/thermal temperature ``` 模型预测的合成目标: ``` Brake_Temp_Target ``` ### 异常隔离引擎 在 `src/models/autoencoder.py` 中实现。 自编码器基于残差进行训练: ``` abs(actual_temperature - predicted_temperature) ``` 在推理期间: ``` anomaly_score = reconstruction_loss(residual) is_anomaly = anomaly_score > alert_threshold ``` 阈值在训练期间根据验证残差重建损失计算得出: ``` mean(losses) + z_score_multiplier * std(losses) ``` 乘数配置于: ``` anomaly_detection: initial_threshold: 3.5 ``` ## API 端点 基础 URL: ``` http://localhost:18080 ``` | 方法 | 路径 | 用途 | |---|---|---| | `GET` | `/health` | 存活检查。即使依赖项未就绪,也会返回 API 状态。 | | `GET` | `/ready` | 针对 Redis、DB、Kafka 任务和 worker 的就绪检查。 | | `POST` | `/telemetry` | 可选的直接遥测摄取,进入 worker 队列。 | | `GET` | `/telemetry/latest` | 从 Redis 获取的最新已处理推理结果。 | | `WS` | `/ws/telemetry` | 实时仪表盘遥测流。 | 遥测 payload 示例: ``` { "TimeSec": 85.2, "Speed": 280.0, "Throttle": 40.0, "Brake": 92.0, "RPM": 11200.0, "nGear": 6 } ``` 推理 payload 示例: ``` { "CapturedAt": "2026-07-12T10:20:30.000000+00:00", "TimeSec": 85.2, "Speed": 280.0, "Brake": 92.0, "Predicted_Temp": 203.4, "Actual_Temp": 220.7, "Anomaly_Score": 294.68, "Alert_Threshold": 40783.31, "Is_Anomaly": false } ``` ## Docker Compose 服务 | 服务 | 用途 | |---|---| | `zookeeper` | Kafka 协调。 | | `kafka` | 遥测事件总线。 | | `postgres` | 异步持久化目标。 | | `redis` | 最新推理缓存。 | | `inference-api` | FastAPI 运行时和模型推理 worker。 | | `pitwall-dashboard` | Next.js 仪表盘。 | | `telemetry-replay` | 用于将 CSV 回放到 Kafka 的可选配置文件服务。 | ## 快速开始 ### 1. 构建并启动核心服务 ``` docker compose up --build ``` 打开: ``` http://localhost:8502 ``` 检查 API: ``` curl http://localhost:18080/health curl http://localhost:18080/ready ``` ### 2. 将遥测数据回放到 Kafka 在核心栈健康运行后: ``` docker compose --profile replay run --rm telemetry-replay ``` 仪表盘只有在遥测数据处理完成后才会显示实时指标。它可以通过 `/telemetry/latest` 从 Redis 填充最近处理的点数据。 ### 3. 停止技术栈 ``` docker compose down ``` 删除 PostgreSQL 卷数据: ``` docker compose down -v ``` ## 本地开发 ### 后端 安装完整的本地依赖: ``` pip install -r requirements.txt ``` 本地运行 API: ``` uvicorn api.main:app --host 0.0.0.0 --port 8000 ``` 如果 Windows 阻止了主机端口 `8000`,请使用: ``` uvicorn api.main:app --host 0.0.0.0 --port 18080 ``` ### 仪表盘 ``` cd f1-dashboard npm install npm run dev -- --hostname 127.0.0.1 -p 8502 ``` 仪表盘期望: ``` NEXT_PUBLIC_WS_URL=ws://localhost:18080/ws/telemetry ``` ### 训练 运行完整的训练流水线: ``` python train.py ``` 这将: 1. 通过 FastF1 获取历史遥测数据。 2. 重采样并对齐遥测数据。 3. 生成物理特征。 4. 训练虚拟热力学传感器。 5. 训练残差自编码器。 6. 保存: - `data/virtual_sensor.pt` - `data/isolation_engine.pt` - `data/raw_samples/monza_ver_cleaned.csv` ### 不使用 Docker 进行回放 首先启动 Kafka,然后运行: ``` python src/pipeline/replay_simulation.py ``` 对于本地主机 Kafka: ``` $env:KAFKA_BOOTSTRAP_SERVERS="localhost:9092" python src/pipeline/replay_simulation.py ``` ## 配置 主要配置文件: ``` config/config.yaml ``` 重要字段: | 字段 | 用途 | |---|---| | `system.target_frequency_hz` | 回放和模型采样频率。 | | `features.raw_channels` | 模型使用的原始遥测列。 | | `features.physics_engineered` | 模型使用的物理特征列。 | | `features.target_channel` | 合成训练目标。 | | `model_hyperparameters.sequence_length` | 滚动推理窗口大小。 | | `model_hyperparameters.hidden_dimension` | LSTM 隐藏层大小。 | | `anomaly_detection.initial_threshold` | 用于阈值生成的 Z-score 乘数。 | ## 环境变量 | 变量 | 默认值 | 使用者 | |---|---|---| | `KAFKA_BOOTSTRAP_SERVERS` | `localhost:9092` | API, 回放 | | `KAFKA_TELEMETRY_TOPIC` | `f1-telemetry-bus` | API | | `KAFKA_CONSUMER_GROUP` | `inference-api` | API | | `DATABASE_URL` | `postgresql+asyncpg://f1_telemetry:f1_telemetry@localhost:5432/f1_telemetry` | API | | `REDIS_URL` | `redis://localhost:6379/0` | API | | `WEBSOCKET_POLL_SECONDS` | `0.05` | API | | `INFERENCE_QUEUE_MAX_SIZE` | `2000` | API | | `MODEL_VERSION` | `unknown` | API 持久化 | | `NEXT_PUBLIC_WS_URL` | `ws://localhost:18080/ws/telemetry` | 仪表盘 | ## 验证 后端语法: ``` python -m py_compile api/main.py api/worker.py api/database/models.py api/schemas.py ``` 物理测试: ``` python -m pytest tests/test_physics.py -q ``` Docker Compose 验证: ``` docker compose config --quiet ``` 仪表盘: ``` cd f1-dashboard npm run lint npm run build ``` ## 运维说明 ### Windows 端口 `8000` 某些 Windows 设置会在排除的 TCP 范围内预留端口 `8000`。该项目在主机端口 `18080` 上公开 API,同时保持容器端口为 `8000`。 检查排除的范围: ``` netsh interface ipv4 show excludedportrange protocol=tcp ``` ### Docker 镜像下载 API 镜像通过 `requirements-api.txt` 使用仅支持 CPU 的 PyTorch,以避免庞大的 CUDA 下载。如果在 Torch 下载时停滞,请检查到以下地址的网络/DNS 访问: ``` download.pytorch.org ``` ### 仪表盘数据行为 仪表盘仅推理数据后才会进行渲染。要生成数据: 1. 启动 Compose。 2. 等待 Kafka/API 就绪。 3. 运行回放配置文件。 4. 打开 `http://localhost:8502`。 ### Git 卫生 生成的文件夹和本地缓存会被忽略: - `__pycache__/` - `.pytest_cache/` - `node_modules/` - `.next/` - `data/f1_cache/` - SQLite 缓存文件 模型 checkpoint 和回放 CSV 默认不会被忽略,因为它们是当前可运行原型状态的一部分。 ## 许可证 本项目基于 MIT 许可证授权。详见 `LICENSE.md`。
标签:Apex, AV绕过, F1赛车遥测, FastAPI, PyTorch, 凭据扫描, 实时数据流, 异常检测, 搜索引擎查询, 机器学习, 测试用例, 请求拦截, 逆向工具