bugfixes
This commit is contained in:
parent
c6c6bad6cf
commit
83120174a6
@ -1607,12 +1607,21 @@ def predict_batch(req: PredictBatchRequest):
|
||||
"error": "no paths supplied",
|
||||
}
|
||||
|
||||
imgsz = int(req.imageSize or _IMGSZ or 640)
|
||||
|
||||
current_model = get_model()
|
||||
if current_model is None:
|
||||
predictions = [empty_prediction("detector_model_missing") for _ in paths]
|
||||
if not req.detectorOnly:
|
||||
apply_pose_batch_to_predictions(paths, predictions, imgsz)
|
||||
|
||||
return {
|
||||
"ok": True,
|
||||
"predictions": [empty_prediction("model_missing") for _ in paths],
|
||||
"error": _MODEL_ERROR or f"YOLO model not found: {DEFAULT_MODEL_PATH}",
|
||||
"available": False,
|
||||
"modelAvailable": False,
|
||||
"predictions": predictions,
|
||||
"modelError": _MODEL_ERROR,
|
||||
"expectedModel": str(DEFAULT_MODEL_PATH),
|
||||
}
|
||||
|
||||
if DETECTION_LABELS_PATH is None or _LABEL_ERROR:
|
||||
@ -1622,8 +1631,6 @@ def predict_batch(req: PredictBatchRequest):
|
||||
"error": f"detection labels missing: {_LABEL_ERROR}",
|
||||
}
|
||||
|
||||
imgsz = int(req.imageSize or _IMGSZ or 640)
|
||||
|
||||
try:
|
||||
results = current_model.predict(
|
||||
source=paths,
|
||||
@ -1642,6 +1649,8 @@ def predict_batch(req: PredictBatchRequest):
|
||||
|
||||
return {
|
||||
"ok": True,
|
||||
"available": True,
|
||||
"modelAvailable": True,
|
||||
"predictions": predictions,
|
||||
}
|
||||
|
||||
@ -1703,7 +1712,7 @@ def health():
|
||||
|
||||
status_payload = {
|
||||
"ok": True,
|
||||
"ready": current_model is not None,
|
||||
"ready": True,
|
||||
"modelAvailable": current_model is not None,
|
||||
"model": _MODEL_PATH,
|
||||
"modelError": _MODEL_ERROR,
|
||||
@ -1751,8 +1760,8 @@ def reload_model():
|
||||
names = getattr(current_model, "names", {}) or {} if current_model is not None else {}
|
||||
|
||||
status_payload = {
|
||||
"ok": current_model is not None,
|
||||
"ready": current_model is not None,
|
||||
"ok": True,
|
||||
"ready": True,
|
||||
"modelAvailable": current_model is not None,
|
||||
"model": _MODEL_PATH,
|
||||
"modelError": _MODEL_ERROR,
|
||||
|
||||
BIN
backend/dist/nsfwapp-linux-amd64
vendored
BIN
backend/dist/nsfwapp-linux-amd64
vendored
Binary file not shown.
BIN
backend/dist/nsfwapp.exe
vendored
BIN
backend/dist/nsfwapp.exe
vendored
Binary file not shown.
BIN
backend/dist/nsfwapp_amd64.deb
vendored
BIN
backend/dist/nsfwapp_amd64.deb
vendored
Binary file not shown.
@ -9,6 +9,7 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@ -112,11 +113,22 @@ func mlPythonSetupConfigFromEnv() mlPythonSetupConfig {
|
||||
appDir: filepath.Clean(appDir),
|
||||
requirementsPath: filepath.Clean(requirementsPath),
|
||||
venvDir: filepath.Clean(venvDir),
|
||||
venvPython: filepath.Join(filepath.Clean(venvDir), "bin", "python"),
|
||||
venvPython: mlPythonVenvPythonPath(venvDir),
|
||||
requirementsMark: filepath.Join(filepath.Clean(venvDir), ".requirements-ml.txt"),
|
||||
}
|
||||
}
|
||||
|
||||
func mlPythonVenvPythonPath(venvDir string) string {
|
||||
venvDir = filepath.Clean(strings.TrimSpace(venvDir))
|
||||
if venvDir == "" {
|
||||
return ""
|
||||
}
|
||||
if runtime.GOOS == "windows" {
|
||||
return filepath.Join(venvDir, "Scripts", "python.exe")
|
||||
}
|
||||
return filepath.Join(venvDir, "bin", "python")
|
||||
}
|
||||
|
||||
func defaultMLPythonVenvDir() string {
|
||||
base := strings.TrimSpace(os.TempDir())
|
||||
if base == "" {
|
||||
|
||||
@ -206,6 +206,10 @@ func aiServerPythonPath() string {
|
||||
return raw
|
||||
}
|
||||
|
||||
if venvPython := configuredMLPythonVenvPythonPath(); venvPython != "" {
|
||||
return venvPython
|
||||
}
|
||||
|
||||
// Windows py launcher zuerst versuchen.
|
||||
if runtime.GOOS == "windows" {
|
||||
if _, err := exec.LookPath("py"); err == nil {
|
||||
@ -224,6 +228,34 @@ func aiServerPythonPath() string {
|
||||
return "python"
|
||||
}
|
||||
|
||||
func configuredMLPythonVenvPythonPath() string {
|
||||
if strings.TrimSpace(os.Getenv("NSFWAPP_SKIP_ML_SETUP")) == "1" {
|
||||
return ""
|
||||
}
|
||||
|
||||
candidates := []string{}
|
||||
if venvDir := strings.TrimSpace(os.Getenv("NSFWAPP_ML_VENV")); venvDir != "" {
|
||||
candidates = append(candidates, venvDir)
|
||||
}
|
||||
if strings.TrimSpace(os.Getenv("NSFWAPP_ML_SETUP")) == "1" {
|
||||
candidates = append(candidates, defaultMLPythonVenvDir())
|
||||
}
|
||||
|
||||
seen := map[string]bool{}
|
||||
for _, dir := range candidates {
|
||||
path := mlPythonVenvPythonPath(dir)
|
||||
key := filepath.Clean(path)
|
||||
if path == "" || seen[key] {
|
||||
continue
|
||||
}
|
||||
seen[key] = true
|
||||
if info, err := os.Stat(path); err == nil && info != nil && !info.IsDir() {
|
||||
return path
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func findAIServerScriptDir() (string, error) {
|
||||
cwd, _ := os.Getwd()
|
||||
|
||||
@ -544,7 +576,7 @@ func startAIServer(ctx context.Context) (*aiServerProcess, error) {
|
||||
|
||||
// Modell ebenfalls standardmäßig aus generated/training nehmen,
|
||||
// aber YOLO_MODEL darf weiterhin extern überschrieben werden.
|
||||
if strings.TrimSpace(os.Getenv("YOLO_MODEL")) == "" {
|
||||
if strings.TrimSpace(os.Getenv("YOLO_MODEL")) == "" && defaultModel.EffectiveExists {
|
||||
env = upsertEnv(env, "YOLO_MODEL", defaultModelPath)
|
||||
}
|
||||
|
||||
|
||||
@ -2557,7 +2557,38 @@ func trainingCancelHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func trainingRunJob(ctx context.Context, root string, count int) {
|
||||
if err := ensureMLPythonSetup(ctx); err != nil {
|
||||
if errors.Is(err, context.Canceled) {
|
||||
trainingFinishCancelled(root)
|
||||
return
|
||||
}
|
||||
|
||||
appLogln("ML-Python setup for training failed:", err)
|
||||
trainingSetJobStatus(func(s *TrainingJobStatus) {
|
||||
finishedAt := time.Now().UTC()
|
||||
var durationMs int64
|
||||
if startedAt, parseErr := time.Parse(time.RFC3339, strings.TrimSpace(s.StartedAt)); parseErr == nil {
|
||||
durationMs = finishedAt.Sub(startedAt).Milliseconds()
|
||||
if durationMs < 0 {
|
||||
durationMs = 0
|
||||
}
|
||||
}
|
||||
|
||||
s.Running = false
|
||||
s.Progress = 100
|
||||
s.Step = "Training fehlgeschlagen."
|
||||
s.Message = "ML-Python-Umgebung konnte nicht vorbereitet werden."
|
||||
s.Error = err.Error()
|
||||
s.FinishedAt = finishedAt.Format(time.RFC3339)
|
||||
s.DurationMs = durationMs
|
||||
s.PreviewURL = ""
|
||||
})
|
||||
trainingClearJobCancel()
|
||||
return
|
||||
}
|
||||
|
||||
python := trainingPythonExe()
|
||||
appLogln("ML-Python für Training:", python)
|
||||
|
||||
cleanOutput := func(text string) string {
|
||||
out := strings.TrimSpace(text)
|
||||
@ -6504,7 +6535,7 @@ func trainingPythonExe() string {
|
||||
if v != "" {
|
||||
return v
|
||||
}
|
||||
return "python"
|
||||
return aiServerPythonPath()
|
||||
}
|
||||
|
||||
func trainingProjectRoot() string {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user