diff --git a/config/dev.exs b/config/dev.exs index e1eff2c0..ff6b67fa 100644 --- a/config/dev.exs +++ b/config/dev.exs @@ -86,6 +86,9 @@ config :microwaveprop, Oban, # Enable dev routes for dashboard and mailbox config :microwaveprop, dev_routes: true +# Load ML model at startup (Nx/Axon/EXLA only available in dev/test) +config :microwaveprop, load_ml_model: true + # Use local SRTM1 tiles for elevation lookups instead of the Open-Meteo API config :microwaveprop, srtm_tiles_dir: Path.expand("~/srtm/tiles") diff --git a/lib/microwaveprop/application.ex b/lib/microwaveprop/application.ex index 6d49354d..c112c6c4 100644 --- a/lib/microwaveprop/application.ex +++ b/lib/microwaveprop/application.ex @@ -25,8 +25,10 @@ defmodule Microwaveprop.Application do opts = [strategy: :one_for_one, name: Microwaveprop.Supervisor] result = Supervisor.start_link(children, opts) - # Load ML model after supervision tree is up (non-blocking, no-op if file missing) - Microwaveprop.Propagation.load_ml_model() + # Load ML model in dev/test only (Nx/Axon not compiled for prod) + if Application.get_env(:microwaveprop, :load_ml_model, false) do + Microwaveprop.Propagation.load_ml_model() + end result end diff --git a/lib/microwaveprop/propagation.ex b/lib/microwaveprop/propagation.ex index 982d74b4..649557a9 100644 --- a/lib/microwaveprop/propagation.ex +++ b/lib/microwaveprop/propagation.ex @@ -6,7 +6,6 @@ defmodule Microwaveprop.Propagation do alias Microwaveprop.Propagation.BandConfig alias Microwaveprop.Propagation.Grid alias Microwaveprop.Propagation.GridScore - alias Microwaveprop.Propagation.Model alias Microwaveprop.Propagation.Scorer alias Microwaveprop.Repo alias Microwaveprop.Weather.SoundingParams @@ -14,22 +13,28 @@ defmodule Microwaveprop.Propagation do require Logger @ml_key :propagation_ml + @ml_module Microwaveprop.Propagation.Model @doc """ Loads the ML model from disk, compiles the predict function, and caches both - in persistent_term. No-op if the model file doesn't exist. + in persistent_term. No-op if the model file doesn't exist or ML deps unavailable. """ def load_ml_model do - case Model.load() do - {:ok, params} -> - predict_fn = Model.compile_predict() - :persistent_term.put(@ml_key, {predict_fn, params}) - Logger.info("PropagationML: model loaded and compiled from #{inspect(Model.default_path())}") - :ok + if Code.ensure_loaded?(@ml_module) do + case apply(@ml_module, :load, []) do + {:ok, params} -> + predict_fn = apply(@ml_module, :compile_predict, []) + :persistent_term.put(@ml_key, {predict_fn, params}) + Logger.info("PropagationML: model loaded and compiled") + :ok - :error -> - Logger.info("PropagationML: no model file found, using algorithm scorer only") - :ok + :error -> + Logger.info("PropagationML: no model file found, using algorithm scorer only") + :ok + end + else + Logger.info("PropagationML: ML dependencies not available") + :ok end end diff --git a/lib/microwaveprop/propagation/model.ex b/lib_ml/model.ex similarity index 100% rename from lib/microwaveprop/propagation/model.ex rename to lib_ml/model.ex diff --git a/lib/mix/tasks/propagation_analyze.ex b/lib_ml/propagation_analyze.ex similarity index 100% rename from lib/mix/tasks/propagation_analyze.ex rename to lib_ml/propagation_analyze.ex diff --git a/lib/mix/tasks/propagation_train.ex b/lib_ml/propagation_train.ex similarity index 100% rename from lib/mix/tasks/propagation_train.ex rename to lib_ml/propagation_train.ex diff --git a/mix.exs b/mix.exs index c0c8e887..61b24ee4 100644 --- a/mix.exs +++ b/mix.exs @@ -32,7 +32,8 @@ defmodule Microwaveprop.MixProject do end # Specifies which paths to compile per environment. - defp elixirc_paths(:test), do: ["lib", "test/support"] + defp elixirc_paths(:test), do: ["lib", "lib_ml", "test/support"] + defp elixirc_paths(:dev), do: ["lib", "lib_ml"] defp elixirc_paths(_), do: ["lib"] # Specifies your project dependencies. @@ -65,10 +66,10 @@ defmodule Microwaveprop.MixProject do {:oban, "~> 2.19"}, {:credo, "~> 1.7", only: [:dev, :test], runtime: false}, {:earmark, "~> 1.4"}, - {:nx, "~> 0.9"}, - {:axon, "~> 0.7"}, - {:exla, "~> 0.9"}, - {:polaris, "~> 0.1"} + {:nx, "~> 0.9", only: [:dev, :test]}, + {:axon, "~> 0.7", only: [:dev, :test]}, + {:exla, "~> 0.9", only: [:dev, :test]}, + {:polaris, "~> 0.1", only: [:dev, :test]} ] end