feat: flag forcar_do_zero para treinar do zero ignorando modelo atual
Permite disparar treino com yolov8n limpo (sem fine-tuning) sem apagar o cerebro.pt em produção, que continua servindo o /detectar normalmente enquanto o novo treino roda.
This commit is contained in:
@@ -83,20 +83,29 @@ def carregar_modelo_do_s3(ambiente: str):
|
||||
return MODELOS_CARREGADOS[ambiente]
|
||||
|
||||
|
||||
def _executar_treino_sync(ambiente: str, pular_triagem: bool) -> dict:
|
||||
def _executar_treino_sync(ambiente: str, pular_triagem: bool, forcar_do_zero: bool = False) -> dict:
|
||||
"""Execução síncrona do treino — chamada em background thread."""
|
||||
prefix_novos = f"treinamento/{ambiente}/novos-treinamentos/"
|
||||
objs = s3.list_objects_v2(Bucket=BUCKET, Prefix=prefix_novos)
|
||||
|
||||
# Tenta carregar modelo atual do S3; se não existir, usa YOLO genérico (primeiro treino)
|
||||
try:
|
||||
modelo_base = carregar_modelo_do_s3(ambiente)
|
||||
is_fine_tuning = True
|
||||
except Exception:
|
||||
log_print(f"Nenhum modelo base encontrado para '{ambiente}', iniciando do zero com yolov8n.")
|
||||
if forcar_do_zero:
|
||||
# Ignora o cerebro.pt atual só para efeito de treino — o arquivo em
|
||||
# modelos/{ambiente}/atual/cerebro.pt não é tocado, então o /detectar
|
||||
# em produção continua servindo normalmente enquanto este treino roda.
|
||||
log_print(f"Treino do zero forçado para '{ambiente}' — ignorando modelo atual.")
|
||||
modelo_base = YOLO('yolov8n.pt')
|
||||
is_fine_tuning = False
|
||||
pular_triagem = True # triagem sem modelo próprio é inútil
|
||||
pular_triagem = True # sem modelo próprio confiável, triagem não faz sentido
|
||||
else:
|
||||
# Tenta carregar modelo atual do S3; se não existir, usa YOLO genérico (primeiro treino)
|
||||
try:
|
||||
modelo_base = carregar_modelo_do_s3(ambiente)
|
||||
is_fine_tuning = True
|
||||
except Exception:
|
||||
log_print(f"Nenhum modelo base encontrado para '{ambiente}', iniciando do zero com yolov8n.")
|
||||
modelo_base = YOLO('yolov8n.pt')
|
||||
is_fine_tuning = False
|
||||
pular_triagem = True # triagem sem modelo próprio é inútil
|
||||
|
||||
if pular_triagem:
|
||||
log_print(f"TRIAGEM PULADA: movendo todos os arquivos direto para base-oficial ({ambiente})")
|
||||
@@ -198,12 +207,12 @@ def _executar_treino_sync(ambiente: str, pular_triagem: bool) -> dict:
|
||||
return {"status": "vazio"}
|
||||
|
||||
|
||||
def _treinar_bg(ambiente: str, pular_triagem: bool):
|
||||
def _treinar_bg(ambiente: str, pular_triagem: bool, forcar_do_zero: bool = False):
|
||||
global _treinamento_status
|
||||
with _status_lock:
|
||||
_training_logs.clear()
|
||||
try:
|
||||
resultado = _executar_treino_sync(ambiente, pular_triagem)
|
||||
resultado = _executar_treino_sync(ambiente, pular_triagem, forcar_do_zero)
|
||||
with _status_lock:
|
||||
if resultado["status"] == "sucesso":
|
||||
_treinamento_status = {
|
||||
@@ -256,9 +265,10 @@ async def treinar(dados: dict):
|
||||
raise HTTPException(status_code=409, detail="Treinamento já em andamento")
|
||||
ambiente = dados.get("ambiente", "gondola")
|
||||
pular_triagem = dados.get("pular_triagem", False)
|
||||
forcar_do_zero = dados.get("forcar_do_zero", False)
|
||||
_treinamento_status = {"status": "running", "ambiente": ambiente, "versao": None, "detalhe": None}
|
||||
|
||||
threading.Thread(target=_treinar_bg, args=(ambiente, pular_triagem), daemon=True).start()
|
||||
threading.Thread(target=_treinar_bg, args=(ambiente, pular_triagem, forcar_do_zero), daemon=True).start()
|
||||
return {"status": "iniciado", "ambiente": ambiente}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user