# SpecDetect4ML: Detecting Non-Local ML Code Smells with Code Property Graphs

arXiv: https://arxiv.org/abs/2509.20491 · HTML: https://mlsanity.com/paper/2509.20491/

## Key facts

- Cited by 1 papers in the map (data through 14 Oct 2026).
- Builds on 4 of its 24 references that are in the map.
- First posted on arXiv 24 Sep 2025.

## Builds on (most cited first, 4 of 4)

- [A Synthesis of Green Architectural Tactics for ML-Enabled Systems](https://mlsanity.com/paper/2312.09610/) (2023)
- [Code Smells for Machine Learning Applications](https://mlsanity.com/paper/2203.13746/) (2022)
- [Ariadne: Analysis for Machine Learning Program](https://mlsanity.com/paper/1805.04058/) (2018)
- [When Code Smells Meet ML: On the Lifecycle of ML-specific Code Smells in ML-enabled Systems](https://mlsanity.com/paper/2403.08311/) (2024)

## Built on by (most cited first, 1 of 1)

- [LLM Code Smells: A Taxonomy and Detection Approach](https://mlsanity.com/paper/2605.22976/) (2026)

## Abstract (arXiv)

Machine Learning (ML) pipelines encode quality-relevant decisions across data preparation, training, evaluation, and configuration code. Some recurring source-level quality problems in these pipelines, known as ML code smells, may not cause immediate failures but can harm reproducibility, robustness, efficiency, or maintainability. Detecting ML code smell occurrences is challenging because the decisive evidence is often non-local, spanning helper functions, wrappers, imports, control-flow, and data-flow relations. We present SpecDetect4ML, a static analyser that operationalises 22 ML code smells using CPG views with project-level resolution. We evaluate it on 890 Python ML-based systems comprising more than 20M LOC and a system-level recall benchmark over the complete ML-relevant source subset of 10 selected systems. Under identical ML code smell specifications, CPG-based reasoning raises recall from 68.62% to 88.14% compared with AST-only analysis, while keeping CPG precision comparable at 90.32%. These results show that project-level static reasoning expands the detectable portion of non-local ML code smell occurrences, while configuration-dependent and runtime-only occurrences remain outside our source-only static claims.
