Packages

Model versioning, artifact storage, and lineage tracking for ML pipelines

Current section

4 Versions

Jump to

Compare versions

6 files changed
+113 additions
-8 deletions
  @@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file.
5 5 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6 6 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 7
8 + ## [0.2.0] - 2025-12-27
9 +
10 + ### Added
11 +
12 + - Conformance tests for all model registry stages
13 + - README documentation for stage contracts with detailed option tables
14 +
15 + ### Changed
16 +
17 + - Updated crucible_framework dependency to ~> 0.5.0
18 +
19 + ### Stages
20 +
21 + - Register - Model version registration with lineage tracking
22 + - Promote - Lifecycle stage promotion (development -> staging -> production)
23 +
8 24 ## [0.1.0] - 2025-12-25
9 25
10 26 ### Added
  @@ -124,18 +124,71 @@ descendants = CrucibleModelRegistry.get_descendants(version)
124 124 :ok = CrucibleModelRegistry.download_artifact(artifact, "/tmp/model.bin")
125 125 ```
126 126
127 - ## Crucible Stages
127 + ## Model Registry Stages
128 +
129 + This package provides Crucible stages for model lifecycle management:
130 +
131 + - `:model_register` - Register trained model versions with lineage tracking
132 + - `:model_promote` - Promote model versions through lifecycle stages
133 +
134 + All stages implement the `Crucible.Stage` behaviour with full describe/1 schemas.
135 +
136 + ### Register Stage
137 +
138 + Registers a trained model version in the model registry.
139 +
140 + #### Required Options
141 +
142 + | Option | Type | Description |
143 + |--------|------|-------------|
144 + | `:model_name` | `:string` | Name of the model |
145 + | `:recipe` | `:atom` | Training recipe used |
146 + | `:base_model` | `:string` | Base model identifier |
147 +
148 + #### Optional Options
149 +
150 + | Option | Type | Description |
151 + |--------|------|-------------|
152 + | `:version` | `:string` | Version string (auto-generated if not provided) |
153 + | `:training_config` | `:map` | Training configuration |
154 + | `:artifacts` | `{:list, :map}` | List of artifact metadata |
155 + | `:parent_version_id` | `:string` | Parent version for lineage |
156 + | `:lineage_type` | `{:enum, [:fine_tune, :distillation, :merge]}` | Type of lineage relationship |
157 +
158 + #### Example
128 159
129 160 ```elixir
130 161 CrucibleModelRegistry.Stages.Register.run(context,
131 162 model_name: "math-tutor",
132 163 version: "1.0.0",
133 - recipe: "sl_basic",
164 + recipe: :sl_basic,
134 165 base_model: "meta-llama/Llama-3.1-8B",
135 166 training_config: %{"lr" => 1.0e-4}
136 167 )
137 168 ```
138 169
170 + ### Promote Stage
171 +
172 + Promotes a model version to a lifecycle stage.
173 +
174 + #### Required Options
175 +
176 + | Option | Type | Description |
177 + |--------|------|-------------|
178 + | `:stage` | `{:enum, [:development, :staging, :production, :archived]}` | Target lifecycle stage |
179 +
180 + #### Optional Options
181 +
182 + | Option | Type | Description |
183 + |--------|------|-------------|
184 + | `:version` | `:map` | Model version (uses context artifact if not provided) |
185 +
186 + #### Example
187 +
188 + ```elixir
189 + CrucibleModelRegistry.Stages.Promote.run(context, stage: :production)
190 + ```
191 +
139 192 ## Telemetry
140 193
141 194 Events emitted:
  @@ -4,7 +4,7 @@
4 4 {<<"Online documentation">>,
5 5 <<"https://hexdocs.pm/crucible_model_registry">>}]}.
6 6 {<<"name">>,<<"crucible_model_registry">>}.
7 - {<<"version">>,<<"0.1.0">>}.
7 + {<<"version">>,<<"0.2.0">>}.
8 8 {<<"description">>,
9 9 <<"Model versioning, artifact storage, and lineage tracking for ML pipelines">>}.
10 10 {<<"elixir">>,<<"~> 1.18">>}.
  @@ -93,11 +93,11 @@
93 93 [{<<"name">>,<<"crucible_framework">>},
94 94 {<<"app">>,<<"crucible_framework">>},
95 95 {<<"optional">>,false},
96 - {<<"requirement">>,<<"~> 0.4.0">>},
96 + {<<"requirement">>,<<"~> 0.5.0">>},
97 97 {<<"repository">>,<<"hexpm">>}],
98 98 [{<<"name">>,<<"crucible_ir">>},
99 99 {<<"app">>,<<"crucible_ir">>},
100 100 {<<"optional">>,false},
101 - {<<"requirement">>,<<"~> 0.2.0">>},
101 + {<<"requirement">>,<<"~> 0.2.1">>},
102 102 {<<"repository">>,<<"hexpm">>}]]}.
103 103 {<<"build_tools">>,[<<"mix">>]}.
  @@ -5,7 +5,22 @@ defmodule CrucibleModelRegistry.Stages.Promote do
5 5 @behaviour Crucible.Stage
6 6 end
7 7
8 + @impl true
9 + def describe(_opts) do
10 + %{
11 + name: :model_promote,
12 + description: "Promotes a model version to a lifecycle stage (staging, production, etc.)",
13 + required: [:stage],
14 + optional: [:version],
15 + types: %{
16 + stage: {:enum, [:development, :staging, :production, :archived]},
17 + version: :map
18 + }
19 + }
20 + end
21 +
8 22 @doc "Run the promote stage."
23 + @impl true
9 24 @spec run(term(), map()) :: {:ok, term()} | {:error, term()}
10 25 def run(context, opts) when is_map(opts) do
11 26 stage = Map.fetch!(opts, :stage)
  @@ -5,7 +5,28 @@ defmodule CrucibleModelRegistry.Stages.Register do
5 5 @behaviour Crucible.Stage
6 6 end
7 7
8 + @impl true
9 + def describe(_opts) do
10 + %{
11 + name: :model_register,
12 + description: "Registers a trained model version in the model registry",
13 + required: [:model_name, :recipe, :base_model],
14 + optional: [:version, :training_config, :artifacts, :parent_version_id, :lineage_type],
15 + types: %{
16 + model_name: :string,
17 + recipe: :atom,
18 + base_model: :string,
19 + version: :string,
20 + training_config: :map,
21 + artifacts: {:list, :map},
22 + parent_version_id: :string,
23 + lineage_type: {:enum, [:fine_tune, :distillation, :merge]}
24 + }
25 + }
26 + end
27 +
8 28 @doc "Run the registration stage."
29 + @impl true
9 30 @spec run(term(), map()) :: {:ok, term()} | {:error, term()}
10 31 def run(context, opts) when is_map(opts) do
11 32 artifacts = resolve_artifacts(context, opts)
Loading more files…