|
|
import click |
|
|
from asyncio import run |
|
|
from pathlib import Path |
|
|
from logging import getLogger, DEBUG, INFO, WARNING, basicConfig |
|
|
import asyncio |
|
|
|
|
|
from scorevision.cli.runner import runner_loop |
|
|
from scorevision.cli.push import push_ml_model |
|
|
from scorevision.utils.settings import get_settings |
|
|
from scorevision.cli.signer_api import run_signer |
|
|
from scorevision.cli.validate import _validate_main |
|
|
from scorevision.utils.prometheus import _start_metrics, mark_service_ready |
|
|
from scorevision.cli.run_vlm_pipeline import run_vlm_pipeline_once_for_single_miner |
|
|
|
|
|
logger = getLogger(__name__) |
|
|
|
|
|
|
|
|
@click.group(name="sv") |
|
|
@click.option( |
|
|
"-v", |
|
|
"--verbosity", |
|
|
count=True, |
|
|
help="Increase verbosity (-v INFO, -vv DEBUG)", |
|
|
) |
|
|
def cli(verbosity: int): |
|
|
"""Score Vision CLI""" |
|
|
settings = get_settings() |
|
|
basicConfig( |
|
|
level=DEBUG if verbosity == 2 else INFO if verbosity == 1 else WARNING, |
|
|
format="%(asctime)s %(levelname)-8s [%(name)s] %(message)s", |
|
|
datefmt="%Y-%m-%d %H:%M:%S", |
|
|
) |
|
|
logger.debug(f"Score Vision started (version={settings.SCOREVISION_VERSION})") |
|
|
|
|
|
|
|
|
@cli.command("runner") |
|
|
def runner_cmd(): |
|
|
"""Launches runner every TEMPO blocks.""" |
|
|
_start_metrics() |
|
|
mark_service_ready("runner") |
|
|
asyncio.run(runner_loop()) |
|
|
|
|
|
|
|
|
@cli.command("push") |
|
|
@click.option( |
|
|
"--model-path", |
|
|
default=None, |
|
|
help="Local path to model artifacts. If none provided, upload skipped", |
|
|
) |
|
|
@click.option( |
|
|
"--revision", |
|
|
default=None, |
|
|
help="Explicit revision SHA to commit (otherwise auto-detected).", |
|
|
) |
|
|
@click.option("--no-deploy", is_flag=True, help="Skip Chutes deployment (HF only).") |
|
|
@click.option( |
|
|
"--no-commit", is_flag=True, help="Skip on-chain commitment (print payload only)." |
|
|
) |
|
|
def push( |
|
|
model_path, |
|
|
revision, |
|
|
no_deploy, |
|
|
no_commit, |
|
|
): |
|
|
"""Push the miner's ML model stored on Huggingface onto Chutes and commit information on-chain""" |
|
|
try: |
|
|
run( |
|
|
push_ml_model( |
|
|
ml_model_path=Path(model_path) if model_path else None, |
|
|
hf_revision=revision, |
|
|
skip_chutes_deploy=no_deploy, |
|
|
skip_bittensor_commit=no_commit, |
|
|
) |
|
|
) |
|
|
except Exception as e: |
|
|
click.echo(e) |
|
|
|
|
|
|
|
|
@cli.command("signer") |
|
|
def signer_cmd(): |
|
|
asyncio.run(run_signer()) |
|
|
|
|
|
|
|
|
@cli.command("validate") |
|
|
@click.option( |
|
|
"--tail", type=int, envvar="SCOREVISION_TAIL", default=28800, show_default=True |
|
|
) |
|
|
@click.option( |
|
|
"--alpha", type=float, envvar="SCOREVISION_ALPHA", default=0.2, show_default=True |
|
|
) |
|
|
@click.option( |
|
|
"--m-min", type=int, envvar="SCOREVISION_M_MIN", default=25, show_default=True |
|
|
) |
|
|
@click.option( |
|
|
"--tempo", type=int, envvar="SCOREVISION_TEMPO", default=100, show_default=True |
|
|
) |
|
|
def validate_cmd(tail: int, alpha: float, m_min: int, tempo: int): |
|
|
""" |
|
|
ScoreVision validator (mainnet cadence): |
|
|
- attend block%tempo==0 |
|
|
- calcule (uids, weights) winner-takes-all |
|
|
- push via signer, fallback local si signer HS |
|
|
""" |
|
|
_start_metrics() |
|
|
mark_service_ready("validator") |
|
|
asyncio.run(_validate_main(tail=tail, alpha=alpha, m_min=m_min, tempo=tempo)) |
|
|
|
|
|
|
|
|
@cli.command("run-once") |
|
|
@click.option("--revision", type=str, default=None) |
|
|
def test_vlm_pipeline(revision: str) -> None: |
|
|
"""Run the miner on the VLM-as-Judge pipeline off-chain (results not saved)""" |
|
|
try: |
|
|
result = run(run_vlm_pipeline_once_for_single_miner(hf_revision=revision)) |
|
|
click.echo(result) |
|
|
except Exception as e: |
|
|
click.echo(e) |
|
|
|