Revue de code — FastCrowdVision
Bonjour à toutes et à tous,
Voici ma revue de code sur votre projet. Bravo pour le travail accompli — détecter des personnes en temps réel sur vidéo avec une architecture entraînée from scratch, c'est un beau défi que vous avez relevé avec soin. Les remarques qui suivent portent sur quelques détails de bonnes pratiques vus en cours, le fond est vraiment solide.
Points forts
Structure du projet
La séparation entre model/, serving/, training/, tests/ et website/ est claire
et cohérente. Chaque module a une responsabilité bien définie, ce qui correspond à la
structure modulaire recommandée dans le cours (App 4–6).
Docker
Le multi-stage build est bien pensé. La séparation des dépendances entre
requirements.txt (entraînement + dev) et requirements-api.txt (API uniquement)
permet de garder l'image de production légère. Le .dockerignore est également présent,
ce qui est souvent omis.
CI/CD
Le workflow docker-deploy.yml utilise docker/metadata-action pour gérer le tagging
des images automatiquement — nom de branche pour les branches de développement, latest
réservé à main. Cette approche évite les tags codés en dur et s'aligne avec les
recommandations du cours (App 14–15).
GitOps avec ArgoCD
argocd/application.yaml est présent et configuré avec auto-sync, prune et self-heal.
Le README est transparent sur la limitation du SSPCloud concernant l'accès restreint au
namespace argocd, ce qui est appréciable.
Kubernetes
Les quatre manifests sont présents (deployment, service, ingress, pvc), ce qui
correspond au déploiement complet couvert en App 18.
Tests
La suite de tests couvre les forward passes SSD sur les quatre backbones ainsi que le
Hard Negative Mining. Le recours à des fonctions utilitaires évite la répétition et
l'ensemble est bien structuré.
inference.py et server.py
La séparation entre le chargement du modèle et la détection frame par frame est propre.
La boucle WebSocket dans server.py gère correctement les cas limites : nettoyage des
fichiers temporaires, gestion des erreurs dans le bloc finally, et asyncio.sleep(0)
pour ne pas bloquer l'event loop.
Versionnement du modèle
Stocker les poids du modèle sur HuggingFace plutôt que dans le dépôt est une bonne
pratique. La logique de chargement dans inference.py via hf_hub_download avec mise
en cache locale est propre.
Pistes d'amélioration
1. Absence d'un pipeline de tests automatisé
pytest est mentionné dans le README mais il n'existe pas de workflow GitHub Actions
qui exécute la suite de tests automatiquement à chaque push ou pull request. C'est l'une
des recommandations explicites du cours (App 14). Un changement introduisant une
régression pourrait donc passer inaperçu jusqu'à ce que quelqu'un lance les tests
manuellement. Ajouter un workflow tests.yml permettrait de combler cette lacune :
name: Run tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: pip install -r requirements/requirements-api.txt pytest
- name: Run tests
run: pytest tests/ -v
2. Absence de pre-commit hooks
ruff est configuré dans pyproject.toml mais il n'existe pas de .pre-commit-config.yaml,
ce qui signifie que le linting n'est pas appliqué avant chaque commit. Le cours aborde
ce point en App 2. Ajouter un hook pre-commit avec ruff permettrait de l'exécuter
systématiquement plutôt que de le laisser disponible sans être déclenché :
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.4.0
hooks:
- id: ruff
- id: ruff-format
3. Gestion des dépendances
Le cours recommande uv comme gestionnaire de dépendances (App 3), notamment pour les
garanties de reproductibilité offertes par uv.lock. La configuration actuelle repose
sur pip + venv, ce qui fonctionne mais n'offre pas le même niveau de reproductibilité.
On notera que uv.lock est mentionné — et commenté — dans le .gitignore, ce qui
suggère que uv avait été envisagé. La migration serait relativement simple puisque
pyproject.toml est déjà en place.
4. main.ipynb à la racine
Le notebook main.ipynb se trouve à la racine du dépôt. La structure cookiecutter
recommandée dans le cours (App 4) place les notebooks dans un dossier notebooks/
dédié, afin de garder la racine lisible et de séparer clairement le travail exploratoire
du code de production.
Bonne continuation à tous !
Revue de code — FastCrowdVision
Bonjour à toutes et à tous,
Voici ma revue de code sur votre projet. Bravo pour le travail accompli — détecter des personnes en temps réel sur vidéo avec une architecture entraînée from scratch, c'est un beau défi que vous avez relevé avec soin. Les remarques qui suivent portent sur quelques détails de bonnes pratiques vus en cours, le fond est vraiment solide.
Points forts
Structure du projet
La séparation entre
model/,serving/,training/,tests/etwebsite/est claireet cohérente. Chaque module a une responsabilité bien définie, ce qui correspond à la
structure modulaire recommandée dans le cours (App 4–6).
Docker
Le multi-stage build est bien pensé. La séparation des dépendances entre
requirements.txt(entraînement + dev) etrequirements-api.txt(API uniquement)permet de garder l'image de production légère. Le
.dockerignoreest également présent,ce qui est souvent omis.
CI/CD
Le workflow
docker-deploy.ymlutilisedocker/metadata-actionpour gérer le taggingdes images automatiquement — nom de branche pour les branches de développement,
latestréservé à
main. Cette approche évite les tags codés en dur et s'aligne avec lesrecommandations du cours (App 14–15).
GitOps avec ArgoCD
argocd/application.yamlest présent et configuré avec auto-sync, prune et self-heal.Le README est transparent sur la limitation du SSPCloud concernant l'accès restreint au
namespace
argocd, ce qui est appréciable.Kubernetes
Les quatre manifests sont présents (
deployment,service,ingress,pvc), ce quicorrespond au déploiement complet couvert en App 18.
Tests
La suite de tests couvre les forward passes SSD sur les quatre backbones ainsi que le
Hard Negative Mining. Le recours à des fonctions utilitaires évite la répétition et
l'ensemble est bien structuré.
inference.pyetserver.pyLa séparation entre le chargement du modèle et la détection frame par frame est propre.
La boucle WebSocket dans
server.pygère correctement les cas limites : nettoyage desfichiers temporaires, gestion des erreurs dans le bloc
finally, etasyncio.sleep(0)pour ne pas bloquer l'event loop.
Versionnement du modèle
Stocker les poids du modèle sur HuggingFace plutôt que dans le dépôt est une bonne
pratique. La logique de chargement dans
inference.pyviahf_hub_downloadavec miseen cache locale est propre.
Pistes d'amélioration
1. Absence d'un pipeline de tests automatisé
pytestest mentionné dans le README mais il n'existe pas de workflow GitHub Actionsqui exécute la suite de tests automatiquement à chaque push ou pull request. C'est l'une
des recommandations explicites du cours (App 14). Un changement introduisant une
régression pourrait donc passer inaperçu jusqu'à ce que quelqu'un lance les tests
manuellement. Ajouter un workflow
tests.ymlpermettrait de combler cette lacune :2. Absence de pre-commit hooks
ruffest configuré danspyproject.tomlmais il n'existe pas de.pre-commit-config.yaml,ce qui signifie que le linting n'est pas appliqué avant chaque commit. Le cours aborde
ce point en App 2. Ajouter un hook
pre-commitavecruffpermettrait de l'exécutersystématiquement plutôt que de le laisser disponible sans être déclenché :
3. Gestion des dépendances
Le cours recommande
uvcomme gestionnaire de dépendances (App 3), notamment pour lesgaranties de reproductibilité offertes par
uv.lock. La configuration actuelle reposesur
pip+venv, ce qui fonctionne mais n'offre pas le même niveau de reproductibilité.On notera que
uv.lockest mentionné — et commenté — dans le.gitignore, ce quisuggère que
uvavait été envisagé. La migration serait relativement simple puisquepyproject.tomlest déjà en place.4.
main.ipynbà la racineLe notebook
main.ipynbse trouve à la racine du dépôt. La structure cookiecutterrecommandée dans le cours (App 4) place les notebooks dans un dossier
notebooks/dédié, afin de garder la racine lisible et de séparer clairement le travail exploratoire
du code de production.
Bonne continuation à tous !