Current section
4 Versions
Jump to
Current section
4 Versions
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…