Skip to main content

SPARC-LLM framework with sklearn-inspired object API

Project description

SPARC-LLM Framework

SPARC-LLM is now organized as a reusable Python framework (scikit-learn inspired) with object-oriented APIs, typed configs, service layers, and a stable CLI.

CI Tests Lint Versioning Package


Functional overview (what it does)

This framework helps you run continual learning for LLMs in a clean, reusable way:

  • decompose a base model in SVD space,
  • train an SVF policy to preserve important capabilities,
  • inject new knowledge with orthogonal LoRA,
  • evaluate base/SVF/LoRA/hybrid variants on knowledge + downstream tasks.

Typical user scenarios

  • Research iteration: quickly test a new knowledge dataset while tracking skill retention.
  • Benchmarking: compare none vs svf_only vs lora_only vs both.
  • Pipeline integration: call framework objects from another Python project.
  • Progressive industrialization: keep research code, but expose a clean API for tests and automation.

End-to-end functional flow

flowchart LR
    A[Base model] --> B[SVD decomposition]
    B --> C[SVF training]
    C --> D[Orthogonal LoRA training]
    D --> E[Merge modes: none/svf/lora/both]
    E --> F[Knowledge + downstream evaluation]

Quick execution paths

  • Python-first: use SPARCExperiment.run(...) for orchestration.
  • CLI-first: use sparcllm run ... for end-to-end execution.
  • Stage-by-stage: use sparcllm decompose, train-svf, train-orthogonal, evaluate.

Explainability first (non-technical)

If you are not deeply technical, think about this framework as a way to teach new knowledge to an AI model without making it forget what it already knows.

Intuition of each method

  • SVD (decomposition)
    The model is split into reusable building blocks, like separating a recipe into ingredients.
    Why: it makes later updates more controlled and easier to analyze.

  • SVF (stability policy training)
    The framework learns which internal directions are important to keep stable.
    Why: this protects useful existing skills (reasoning, coding patterns, etc.).

  • Orthogonal LoRA (knowledge injection)
    LoRA adds new knowledge through lightweight adapters. “Orthogonal” means the update is guided to avoid conflicting with protected directions.
    Why: inject new facts while reducing catastrophic forgetting.

  • Merge + evaluation
    You can compare multiple versions of the model:

    • base only,
    • SVF only,
    • LoRA only,
    • SVF + LoRA together.
      Why: measure what really works before deployment.

What happens when you run one full command

When you launch:

sparcllm run \
  --with-svd \
  --with-svf \
  --with-orthogonal \
  --with-eval \
  --model-id meta-llama/Llama-3.1-8B-Instruct \
  --base-model-key llama3i8b \
  --svf-checkpoint-path svf_adapters/gsm_131224_policy_params.pt \
  --knowledge-dataset-file knowledge_injection_data/500UK_3rHK.csv \
  --svf-params-path svf_adapters/gsm_131224_policy_params.pt \
  --svd-params-path svd_parameters/llama3.1_decomposed_params.pt \
  --lora-adapter-path results_orthogonal/<run>/lora_epoch_10 \
  --eval-mode both \
  --task-names gsm8k arc

the framework does this, in order:

  1. decomposes the base model (--with-svd),
  2. trains/uses SVF to mark stability directions (--with-svf),
  3. trains orthogonal LoRA for new knowledge (--with-orthogonal),
  4. evaluates the final setup (--with-eval) on selected tasks.

Human explanation of key flags

  • --model-id ...
    Which foundation model you start from.

  • --base-model-key llama3i8b
    Which internal preset/config to use for training defaults.

  • --svf-checkpoint-path ...
    Previously learned SVF stability knowledge (what should be preserved).

  • --knowledge-dataset-file ...
    The file containing new knowledge you want to teach.

  • --svf-params-path ... and --svd-params-path ...
    Technical files needed to rebuild and apply stability-aware modifications.

  • --lora-adapter-path ...
    The LoRA adapter produced by orthogonal training (the “new knowledge module”).

  • --eval-mode both
    Evaluate the combined model (SVF + LoRA).
    Other modes let you compare components separately.

  • --task-names gsm8k arc
    Which benchmarks to run for quality checks.

How to read results simply

  • If knowledge metrics improve and baseline skills stay stable, your run is successful.
  • If knowledge improves but old skills drop strongly, increase preservation constraints (SVF/orthogonal settings).
  • If everything drops, reduce training aggressiveness (learning rate, epochs, adapter rank, batch size).

What you get

  • clean Python objects for each stage (fit, evaluate, run)
  • typed configs with dataclasses
  • layered architecture (datasets, models, trainers, evaluators)
  • one orchestrator object for full experiments
  • installable package with CLI (sparcllm)
  • tests + pre-commit baseline for quality

Installation

python3.11 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
cd evaluation/fishfarm && pip install -e . && cd ../..
pip install -e .

Install from PyPI

pip install sparcllm

The wheel includes the sparcllm.tasks package (downstream benchmarks wired through fishfarm). For ModelMergerEvaluator, Hydra research configs, and anything that runs vLLM-backed evaluation, install the optional extra:

pip install "sparcllm[eval]"

That pulls fishfarm, vllm, and datasets (Hugging Face). Without it, you can still import configs and estimators; evaluation fails at runtime with a clear missing-dependency error once tasks or vLLM are needed.

Auth + env:

hf auth login --token YOURTOKEN
export HF_TOKEN=YOURTOKEN
export CUDA_VISIBLE_DEVICES=0

Python API examples

1) Full workflow with SPARCExperiment

from sparcllm import (
    MergeConfig,
    OrthogonalTrainingConfig,
    SPARCExperiment,
    SVDConfig,
    SVFTrainingConfig,
)

exp = SPARCExperiment(project_root=".")
report = exp.run(
    svd_cfg=SVDConfig(
        model_id="meta-llama/Llama-3.1-8B-Instruct",
        output_file="svd_parameters/llama3.1_decomposed_params.pt",
    ),
    svf_cfg=SVFTrainingConfig(
        base_model_key="llama3i8b",
        mode="training",
        optimization="reinforce",
    ),
    orthogonal_cfg=OrthogonalTrainingConfig(
        base_model_key="llama3i8b",
        svf_checkpoint_path="svf_adapters/gsm_131224_policy_params.pt",
        knowledge_dataset_file="knowledge_injection_data/500UK_3rHK.csv",
        run_name="exp_v2",
    ),
    merge_cfg=MergeConfig(
        base_model_id="meta-llama/Llama-3.1-8B-Instruct",
        lora_adapter_path="results_orthogonal/<run>/lora_epoch_10",
        svf_params_path="svf_adapters/gsm_131224_policy_params.pt",
        svd_params_path="svd_parameters/llama3.1_decomposed_params.pt",
        mode="both",
        task_names=["gsm8k", "arc"],
    ),
)

print(report.executed_stages, report.metrics)

2) Estimator-style partial execution

from sparcllm import MergeConfig, ModelMergerEvaluator

metrics = ModelMergerEvaluator(
    MergeConfig(
        base_model_id="meta-llama/Llama-3.1-8B-Instruct",
        mode="none",
        task_names=["gsm8k"],
        skip_knowledge_eval=True,
    )
).evaluate()

print(metrics)

CLI usage

Stage-by-stage

sparcllm decompose \
  --model-id meta-llama/Llama-3.1-8B-Instruct \
  --output-file svd_parameters/llama3.1_decomposed_params.pt
sparcllm train-svf \
  --base-model-key llama3i8b \
  --mode training \
  --optimization reinforce
sparcllm train-orthogonal \
  --base-model-key llama3i8b \
  --svf-checkpoint-path svf_adapters/gsm_131224_policy_params.pt \
  --knowledge-dataset-file knowledge_injection_data/500UK_3rHK.csv \
  --num-epochs 10 \
  --batch-size 8 \
  --lr 2e-4 \
  --lambda-ip 0 \
  --lambda-ortho 100
sparcllm evaluate \
  --base-model-id meta-llama/Llama-3.1-8B-Instruct \
  --mode both \
  --lora-adapter-path results_orthogonal/<run>/lora_epoch_10 \
  --svf-params-path svf_adapters/gsm_131224_policy_params.pt \
  --svd-params-path svd_parameters/llama3.1_decomposed_params.pt \
  --knowledge-dataset-file knowledge_injection_data/500UK_3rHK.csv \
  --task-names gsm8k arc

One command orchestration

sparcllm run \
  --with-svd \
  --with-svf \
  --with-orthogonal \
  --with-eval \
  --model-id meta-llama/Llama-3.1-8B-Instruct \
  --base-model-key llama3i8b \
  --svf-checkpoint-path svf_adapters/gsm_131224_policy_params.pt \
  --knowledge-dataset-file knowledge_injection_data/500UK_3rHK.csv \
  --svf-params-path svf_adapters/gsm_131224_policy_params.pt \
  --svd-params-path svd_parameters/llama3.1_decomposed_params.pt \
  --lora-adapter-path results_orthogonal/<run>/lora_epoch_10 \
  --eval-mode both \
  --task-names gsm8k arc

Plot and visualize results

You can now generate plots directly from output files with the framework CLI.

1) Plot orthogonal training losses

Input file: training_history.json generated by orthogonal training.

sparcllm plot \
  --kind orthogonal_history \
  --input-file results_orthogonal/<run>/training_history.json \
  --output-dir plots

2) Plot LoRA training curves (Unknown/HighlyKnown/Loss)

Input file: training_log.json (JSONL or concatenated JSON objects).

sparcllm plot \
  --kind lora_training_log \
  --input-file results_sft/<run>/training_log.json \
  --output-dir plots

3) Plot merge/evaluation metrics

Input file: results.json from merge/eval runs.

sparcllm plot \
  --kind merge_results \
  --input-file results_merge_adapters/<timestamp>/results.json \
  --output-dir plots

The command prints the output image path(s), so you can open them directly.


Internal architecture

flowchart LR
    A[Config objects] --> B[Workflow object]
    B --> C[Training services]
    B --> D[Model composition service]
    B --> E[Evaluation engine]
    C --> F[Hydra research entrypoints]
    D --> G[Base/SVF/LoRA merged model]
    E --> H[Task metrics + report]

Package map

sparcllm/
  __init__.py
  base.py                 # BaseEstimator
  config.py               # dataclass configs
  runner.py               # command execution utility
  pipeline.py             # sklearn-like stage estimators
  workflows.py            # SPARCExperiment + ExperimentReport
  cli.py                  # `sparcllm` command line
  datasets/registry.py    # task registry/factory
  models/composer.py      # base/SVF/LoRA composition
  trainers/stages.py      # SVD/SVF/Orthogonal services
  evaluators/engine.py    # knowledge + downstream evaluation engine
  tasks/                    # downstream + knowledge task wrappers (fishfarm / vLLM)
examples/
  framework_quickstart.py
tests/
  test_base_estimator.py
  test_config_and_pipeline.py

Main objects and what they do

Config objects (sparcllm.config)

  • SVDConfig: controls decomposition stage.
  • SVFTrainingConfig: controls SVF policy training.
  • OrthogonalTrainingConfig: controls orthogonal LoRA training.
  • MergeConfig: controls merge + evaluation stage.
  • ComposeRequest: internal model-composition request.

Estimator objects (sparcllm.pipeline)

  • SVDDecomposer.fit()
  • SVFTrainer.fit()
  • OrthogonalLoRATrainer.fit()
  • ModelMergerEvaluator.evaluate()
  • SPARCPipeline.run(...) (compose multiple stages)

Workflow object (sparcllm.workflows)

  • SPARCExperiment.run(...) returns an ExperimentReport:
    • executed_stages
    • notes
    • metrics

This is the recommended object for production orchestration.


Object interaction diagram

flowchart TD
    C1[SVDConfig]
    C2[SVFTrainingConfig]
    C3[OrthogonalTrainingConfig]
    C4[MergeConfig]

    E[SPARCExperiment]
    R[CommandRunner]
    S1[SVDService]
    S2[SVFTrainingService]
    S3[OrthogonalTrainingService]
    M[ModelComposer]
    EV[EvaluationEngine]
    TR[TaskRegistry]
    REP[ExperimentReport]

    C1 --> E
    C2 --> E
    C3 --> E
    C4 --> E

    E --> R
    E --> S1
    E --> S2
    E --> S3
    E --> EV

    S1 --> R
    S2 --> R
    S3 --> R

    EV --> M
    EV --> TR
    EV --> REP
    E --> REP

How to read this diagram

  • SPARCExperiment is the top-level orchestrator.
  • Config objects define what each stage should do.
  • Training services execute stage logic (currently through managed command calls).
  • EvaluationEngine composes models via ModelComposer, resolves tasks via TaskRegistry, and returns metrics.
  • ExperimentReport is the final structured output for executed stages, notes, and results.

About scripts in scripts/

Legacy shell scripts are still present for reproducibility of older runs.
For new integrations, prefer:

  • Python API via sparcllm objects
  • CLI via sparcllm ...

This keeps your codebase cleaner and easier to test.


Local quality gates

pip install -e ".[dev]"
# optional: fishfarm + vLLM + datasets (matches PyPI `sparcllm[eval]`)
pip install -e ".[eval]"
pre-commit install
pre-commit run --all-files
pytest

Hydra configs under cfgs/ use _target_: sparcllm.tasks.... (task implementations live in the sparcllm.tasks package).


CI/CD and Python artifact publishing

This repository now includes GitHub Actions workflows to validate quality and prepare package publishing.

Workflows added

  • .github/workflows/ci.yml
    • runs lint (ruff) and unit tests (pytest) on PRs and key branches
  • .github/workflows/release.yml
    • resolves version bump from labels (or manual input),
    • bumps package version in pyproject.toml,
    • builds wheel/sdist (python -m build),
    • uploads build artifacts,
    • supports controlled publishing target: none, pypi, artifactory, both,
    • uses Trusted Publisher (OIDC) for PyPI publication.

Versioning strategy (x.y.z)

The release workflow uses semantic versioning:

  • x = major (breaking change)
  • y = minor (new backward-compatible features)
  • z = patch (bug fixes)

Label mapping used by the workflow:

  • major: x, major, semver:major
  • minor: y, minor, semver:minor
  • patch: z, bug, bugfix, patch, semver:patch

If no label is detected, default bump is patch.

Branch strategy for now (before main)

The release workflow is configured to run on:

  • push to code_refactoring
  • push to main/master
  • manual workflow_dispatch

Recommended while preparing:

  • trigger manual runs with publish_target=none to validate build/versioning only,
  • then use publish_target=pypi when you are ready to publish.

Important: on push, the workflow has no publish_target input, so it always stays none. The PyPI and Artifactory steps are skipped on purpose (only build, artifact upload, and version commit run). That is why you may see a “skipped” icon on those steps after a push. To actually upload to PyPI, run Release Package manually and set publish_target to pypi (or both).

Trigger release from code_refactoring (no merge to main)

The GitHub UI Run workflow only appears reliably when the workflow file is on the default branch. To publish from the integration branch without merging to main first, use the GitHub CLI (gh):

# macOS: brew install gh   then: gh auth login
gh workflow run release.yml \
  --ref code_refactoring \
  -f bump=patch \
  -f publish_target=pypi

Adjust bump (patch, minor, major) and publish_target (none, pypi, artifactory, both) as needed. The job runs on the workflow revision present on code_refactoring.

Required secrets for publishing

To publish to your Python artifact repository (Artifactory), set:

  • ARTIFACTORY_PYPI_URL
  • ARTIFACTORY_PYPI_USERNAME
  • ARTIFACTORY_PYPI_PASSWORD

For public PyPI (Trusted Publisher), no API token secret is required when OIDC is configured in PyPI. If publishing target is none, workflow still builds and stores artifacts in GitHub Actions.

The commit version bump step runs only on push and uses the identity github-actions[bot] so git commit works on the runner (no extra secrets needed for that).

Install after publication

Once published in your artifact repository, you can install with:

pip install sparcllm

If your registry is private, configure pip index/auth first (according to your Artifactory or private PyPI setup).


Cleanup performed

  • framework now uses explicit service layers for datasets/models/trainers/evaluators
  • reusable workflow object added (SPARCExperiment)
  • CLI expanded to cover stage-by-stage and end-to-end runs
  • legacy shell scripts kept for reproducibility, framework API prioritized for new usage

This is now a solid base for next steps (deeper tests and artifact publishing pipeline).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sparcllm-2.0.1.tar.gz (35.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sparcllm-2.0.1-py3-none-any.whl (39.5 kB view details)

Uploaded Python 3

File details

Details for the file sparcllm-2.0.1.tar.gz.

File metadata

  • Download URL: sparcllm-2.0.1.tar.gz
  • Upload date:
  • Size: 35.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sparcllm-2.0.1.tar.gz
Algorithm Hash digest
SHA256 9d1f1dfea6ed2f933046d10712b76e3615d4ab448af2e9ad4b78011bebc18c89
MD5 05c96e59ed9e9952de7683add5686515
BLAKE2b-256 1808b06e65113c5e4b7a412cf3f2bcbcc4b917e70bf185b7f4bdfc946f44e74c

See more details on using hashes here.

Provenance

The following attestation bundles were made for sparcllm-2.0.1.tar.gz:

Publisher: release.yml on mustashot/adaptive-llms

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sparcllm-2.0.1-py3-none-any.whl.

File metadata

  • Download URL: sparcllm-2.0.1-py3-none-any.whl
  • Upload date:
  • Size: 39.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sparcllm-2.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1cb758abc3846fd7b5b9c0ade605c16a317cffcd393e6b26a92587b3ac88ccbf
MD5 43e2a6cbf21507425db084448225174c
BLAKE2b-256 3f62f81e311dc7510ebcf757e17aaec650c6d25fd015ba2c768aa8a75de7f5e0

See more details on using hashes here.

Provenance

The following attestation bundles were made for sparcllm-2.0.1-py3-none-any.whl:

Publisher: release.yml on mustashot/adaptive-llms

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page