|
All checks were successful
ENGIN CI / Build, test and smoke (push) Successful in 56s
|
||
|---|---|---|
| .gitea/workflows | ||
| .streamlit | ||
| archive/legacy_experiments | ||
| artifacts/engin-2026.08.25-1 | ||
| assets | ||
| docs | ||
| engin | ||
| presentation | ||
| scripts | ||
| tests | ||
| .dockerignore | ||
| .gitignore | ||
| 1_przebiegi_usterek.png | ||
| 2_przebiegi_silnika.png | ||
| app.py | ||
| baseline_predictions.csv | ||
| benchmark_grouped.py | ||
| compose.prod.yaml | ||
| Dockerfile | ||
| final_pipeline.py | ||
| ml_polish_benchmark.py | ||
| ml_polish_negative_control.csv | ||
| ml_polish_runs.csv | ||
| ml_polish_summary.csv | ||
| prediction_diagnostics.csv | ||
| predictions.csv | ||
| README.md | ||
| requirements-lock.txt | ||
| requirements.txt | ||
| robustness_grouped.py | ||
| ruff.toml | ||
| sample_submit.csv | ||
| severity_benchmark.py | ||
| severity_negative_control.py | ||
| starter.py | ||
| test_benchmark_grouped.py | ||
| test_final_pipeline.py | ||
| test.csv | ||
| train.csv | ||
| val.csv | ||
ENGIN Diagnostic Console
Gotowy do demonstracji system diagnostyki cylindrów przemysłowych silników Diesla. Z pomiaru widma 0–20 kHz rozpoznaje stan każdego cylindra, przewiduje nasilenie usterki i pokazuje mechanikowi, które pasma oraz cylindry wymagają uwagi.
Uruchomienie
Wymagany jest Python 3.12. Artefakt modelu sprawdza zgodność wersji Pythona i bibliotek przed deserializacją.
python -m venv .venv
source .venv/bin/activate
pip install -r requirements-lock.txt
streamlit run app.py
Windows PowerShell:
py -m venv .venv
.venv\Scripts\Activate.ps1
pip install -r requirements-lock.txt
streamlit run app.py
Aplikacja otworzy się pod http://localhost:8501. Od razu uruchamia bezpieczne demo na test.csv; w panelu bocznym można przełączyć się na własny CSV.
Alternatywnie przez Docker:
docker build --target runtime -t engin-console .
docker run --rm -p 127.0.0.1:8501:8501 engin-console
Zalecane uruchomienie produkcyjne korzysta z compose.prod.yaml: kontener działa
jako UID/GID 10001, z systemem plików tylko do odczytu, bez Linux capabilities
oraz z limitami CPU, pamięci i procesów. Pełna procedura startu, aktualizacji i
rollbacku znajduje się w docs/PRODUCTION_RUNBOOK.md.
Co zawiera produkt
- mapa 8-, 12- i 16-cylindrowych silników z diagnozą każdego cylindra,
- typ usterki:
ok,zakoksowany,lejacy,pompa,iglicalubunknown, - nasilenie:
male,srednie,duze; dlaokiunknownzawszenie_dotyczy, - status silnika, najwyższe rzeczywiste severity i kolejka cylindrów do kontroli,
- heatmapa odchyleń całego silnika,
- porównanie widma cylindra z medianą pozostałych cylindrów tej samej jednostki,
- trzy najbardziej anomalne pasma, niekalibrowany score modelu oraz rekomendowany następny krok,
- pobieranie
predictions.csvi rozszerzonej diagnostyki, - ścisła walidacja CSV i bezpieczne komunikaty błędów,
- lokalne działanie na CPU, bez wysyłania danych do zewnętrznych usług.
Architektura
Interfejs jest cienką warstwą prezentacji. Zależności są wstrzykiwane do DiagnosticService, dlatego odczyt pliku, walidator i model można niezależnie wymieniać oraz testować.
Proces produkcyjny nie trenuje modelu przy starcie. Aplikacja weryfikuje checksumę, schemat wejścia i wersje bibliotek, a następnie ładuje artefakt engin-2026.08.25-1. Uszkodzony lub niezgodny artefakt uruchamia ograniczony fallback demonstracyjny.
flowchart TD
UI["Streamlit UI"] --> S["DiagnosticService"]
S --> R["FrameReader"]
S --> V["FrameValidator"]
S --> M["PredictionModel"]
S --> E["Explainability + wykresy"]
Najważniejsze katalogi i pliki:
app.py cienka warstwa Streamlit
engin/io.py adapter odczytu CSV
engin/validation.py kontrakt i walidacja danych
engin/model.py adapter modelu i fallback demo
engin/artifact.py manifest, checksumy i ładowanie artefaktu
engin/features.py stabilne transformacje używane w train/inference
engin/inference.py runtime predykcji bez zależności od benchmarków
engin/service.py przypadek użycia / dependency injection
engin/explainability.py status, porządkowy triage i uzasadnienia
engin/charts.py czyste, testowalne fabryki Plotly
final_pipeline.py finalny pipeline konkursowy
tests/ testy aplikacji, błędów i komponentów
docs/DEMO_SCENARIO.md gotowy scenariusz prezentacji 3–5 min
docs/JURY_QA.md odpowiedzi na typowe pytania jury
Model i wynik
Finalna architektura została wybrana w walidacji StratifiedGroupKFold po engine_id, bez mieszania cylindrów tego samego silnika:
- label: odchylenie od mediany pozostałych cylindrów + Logistic Regression (
C=10), - OOD:
okzmienia się naunknowntylko po przekroczeniu progu 7.25 mV oraz 2.5× mediany anomalii własnego silnika, - severity: cechy odchylenia + Extra Trees (
max_features=0.3), - braki widma: interpolacja wzdłuż częstotliwości z deterministycznym fallbackiem,
- inference na CPU, bez CNN i bez GPU.
| Scenariusz walidacji | Macro F1 | Severity accuracy | Raw Score | Punkty ML |
|---|---|---|---|---|
| clean | 0.9811 | 0.9298 | 0.9683 | 33.65/40 |
| dokładnie 5% braków | 0.9829 | 0.9333 | 0.9705 | 34.10/40 |
To średnie z pięciu seedów walidacji grupowej, nie wynik ukrytego testu. Negative control dla severity pozostaje w okolicy losowego poziomu, co zmniejsza ryzyko pozornego wyniku przez leakage.
Jedynym źródłem finalnych metryk jest ml_polish_benchmark.py oraz pliki ml_polish_summary.csv/ml_polish_runs.csv. Starsze eksperymenty zostały przeniesione do archive/legacy_experiments/ i jawnie oznaczone jako niewłaściwe do raportowania finalnego wyniku.
Score zwracany przez predict_proba służy tylko do względnego porównania predykcji i nie jest przedstawiany jako skalibrowane prawdopodobieństwo awarii. Dla decyzji OOD score label jest celowo pusty, ponieważ OOD jest regułą bezpieczeństwa, a nie klasą modelu probabilistycznego.
Finalne pliki można odtworzyć poleceniem:
python final_pipeline.py
Powstają predictions.csv (600/600 rekordów, bez duplikatów i braków) oraz prediction_diagnostics.csv używany przez aplikację do explainability.
Wersjonowany artefakt modelu buduje osobny krok release:
python -m scripts.build_model_artifact \
--source-revision "$(git rev-parse HEAD)"
python -m scripts.build_model_artifact --verify-only
Druga komenda nie trenuje modelu. Ładuje artefakt, sprawdza manifest i checksumę oraz wymaga dokładnej zgodności wszystkich 600 predykcji z zamrożonym predictions.csv.
Kontrakt danych wejściowych
Każdy wiersz reprezentuje cylinder. Wymagane kolumny:
engine_id,cylinder,n_cylindersrówne 8, 12 albo 16,mV_0…mV_20.
Każdy silnik musi zawierać dokładnie cylindry 1..n_cylinders. Aplikacja odrzuca między innymi puste i zbyt duże pliki, brakujące kolumny, duplikaty cylindrów, tekst w widmie, wartości ujemne/nieskończone, niespójny rozmiar jednostki i ponad 50% braków w jednym cylindrze. Mniejsza liczba braków jest uzupełniana tak samo jak podczas walidacji modelu.
Testy i weryfikacja
Pełna kontrola projektu:
python -m unittest discover -v
Pakiet zawiera 38 testów:
- testy braku leakage, cech, OOD i kontraktu submission,
- testy jednostkowe walidatora i błędnych CSV,
- testy serwisu z fake reader/validator/model — weryfikują dependency injection,
- testy explainability, rankingu i wykresów,
- testy smoke Streamlit dla demo, pustego uploadu i synchronizacji mapy cylindrów ze szczegółami.
- testy artefaktu: checksumy, zgodność bibliotek, brak odczytu danych treningowych przy starcie i regresja predykcji 600/600.
Szybka kontrola serwera:
streamlit run app.py --server.headless true
# drugi terminal
curl --fail http://localhost:8501/_stcore/health
Oczekiwana odpowiedź: ok.
Odporność operacyjna
- Model jest trenowany poza aplikacją i ładowany raz z wersjonowanego artefaktu do cache procesu.
- Finalny obraz runtime nie zawiera
val.csv,train.csvani skryptów treningowych. - Proces aplikacji działa jako użytkownik bez uprawnień roota; produkcyjny Compose dodatkowo wymusza read-only root filesystem, usuwa capabilities i ustawia limity zasobów.
- Nieoczekiwany błąd inicjalizacji modelu uruchamia read-only fallback dla danych demo.
- Nieprawidłowe dane nie docierają do modelu.
- Błędy użytkownika mają stabilne kody i nie pokazują tracebacków w interfejsie.
- Zależności produkcyjne są przypięte w
requirements-lock.txt. - Aplikacja nie zmienia przesłanego pliku i nie wykonuje połączeń zewnętrznych.