pcq — pi/cq agent-operable ML experiment contract library
Project description
pcq
Apache-2.0 오픈소스 ML experiment contract library.
cq.yaml위에서 agent 와 사람이 어떤 ML 코드든 CQ-runnable 실험 단위로 만들 수 있게 한다.
Stable v2.0 baseline — 18 개의 v1.x 릴리즈 (0.1.0 → 0.1.19) 가 통합된 contract runtime API surface 가 안정화되었습니다. CHANGELOG | SPEC | VISION | AGENT_OPERABILITY | ATOM_REGISTRY | RUN_RECORD | CQ_YAML_RUNTIME_CONTRACT | JSON_CONTRACTS | STRICTNESS | WORKER_EXECUTION_FLOW | AGENT_OPERATING_GUIDE | COMPLETION_ROADMAP | CASE_STUDY: MNIST Dogfood
pcq 은 managed service 가 아니라 오픈소스 계약 라이브러리입니다.
라이브러리는 로컬에서 재현 가능한 config, metric, artifact, run summary
계약을 제공하고, cq 서비스는 그 계약을 이용해 원격 실행, 큐, artifact
수집, dashboard, agent feedback loop 를 운영합니다.
pcq is not CQ-only. CQ is one managed consumer of the contract. The same
library can be used by a local script, CI job, notebook workflow, another
orchestrator, or any coding agent that wants cq.yaml + standard artifacts +
machine-readable run evidence.
pcq = open-source agent-operable experiment contract
cq = managed execution + orchestration + result loop
Installation
PyPI distribution name:
pcq. The shortcqname is already occupied on PyPI and also denotes the managed CQ service boundary, so the open-source contract library usespcq. Pythonimport pcqand thepcqCLI command are the public runtime surfaces.
uv add pcq
# Optional extras
uv add 'pcq[vision]' # timm + torchvision
uv add 'pcq[dist]' # accelerate (multi-GPU)
uv add 'pcq[nlp]' # transformers
pyproject.toml:
[project]
dependencies = ["pcq"]
pcq init-experiment --with-pyproject generates a fresh pyproject.toml
with pcq dependencies for you automatically.
If you need to pin a specific tag/branch ahead of a published release, fall back to a git source:
[tool.uv.sources]
pcq = { git = "https://git.pilab.co.kr/pi/pcq.git" }
uv add 'pcq @ git+https://git.pilab.co.kr/pi/pcq.git'
Known limitations (v2.x)
- lineage:
pcq lineageextractsbest_valuefor the head only; ancestors shownull(regression #2). - compare-runs: returns
metric_direction: tiedwhen both runs picked the same best epoch (e.g. same seed). Surface signal can be too coarse for agent next-plan decisions. - validate --plan: catches plan structural errors but does not yet exercise the full label-contract gates that recipe-context validation does.
- catalog scope: contract examples live under
pcq.examples.{models,datasets,optim,sched}plus helper examples (pcq.loss,pcq.metric). They are reference examples for contract verification + onboarding + smoke, not a production catalog — real research atoms live in project-localatoms/(see Project-Local Atoms below).pcq.{models,datasets,optim,sched}remain v2 compatibility facades.
Agent / Worker Docs
For agent and CQ service integration, read these in order:
- CQ YAML Runtime Contract — how
cq.yaml,CQ_CONFIG_JSON, metrics, inputs, andoutput_dirresolve. - Worker Execution Flow — how a CQ worker executes a project and collects standard artifacts.
- Agent Operating Guide — how a coding agent should choose script, Trainer, Experiment, or project-local atoms.
- JSON Contracts — stable machine-readable CLI output contracts for agents and services.
- Strictness Evidence Matrix — evidence required at strictness levels 0..4.
- CQ MCP Tool Spec — service-facing tool surface for structured agent operation.
- Agent Acceptance Checklist — release gates for agent-operable behavior.
- pcq Completion Roadmap — remaining strictness, evidence, E2E, agent-runtime, MCP, and release-hardening work.
Reusable agent assets:
Install those assets into a project explicitly:
# Codex: AGENTS.md + .agents/skills/pcq/SKILL.md
pcq agent install --target codex --path .
# Claude Code: CLAUDE.md + .claude/skills/pcq/SKILL.md
pcq agent install --target claude --path .
# Preview without writing
pcq agent install --target both --path . --dry-run --json
# Inspect installed/missing/stale assets without writing
pcq agent status --target both --path . --json
pcq never modifies project agent files during package installation. Agent
runtime files are created only by pcq agent install or
pcq init-experiment --agent codex|claude|both.
3-Tier API
pcq 은 3 레이어 API 를 제공합니다. 동일한 contract 위에서 어느 레이어든 선택할 수 있고, 위 레이어에서 아래 레이어로 자연스럽게 내려갈 수 있습니다.
Note (v2.7): pcq 내부 atom 들 (
pcq.examples.models.mlp,pcq.examples.datasets.fake,pcq.examples.optim.adamw,pcq.examples.sched.cosine,pcq.loss.cross_entropy등) 은 reference examples — contract 검증 + 온보딩 + smoke baseline 용 예시입니다. production catalog 가 아닙니다. 실제 atom 은 project-local 작성 (Project-Local Atoms 참조).pcq.{models,datasets,optim,sched}는 v2 호환 facade 로 남아 있지만, 문서와 신규 코드는pcq.examples.*또는 project-local atoms 를 사용합니다.
저레벨 — cq.yaml 컨트랙트 API
import pcq
cfg = pcq.config() # CQ_CONFIG_JSON 파싱
pcq.seed_everything(cfg["seed"])
out = pcq.output_dir() # output/ 디렉토리 보장
pcq.log(epoch=1, train_loss=0.42) # stdout @key=value
계약 스크립트는 Trainer/Experiment 없이도 표준 artifact 를 만들 수 있습니다. HF Trainer, TabPFN, PyCaret, sklearn, XGBoost, custom code 모두 이 경로로 연결합니다. framework adapter 는 필요하지 않습니다. 실행 가능한 최소 예제는 examples/contract_numpy.py 입니다.
import pcq
cfg = pcq.config()
out = pcq.output_dir()
pcq.seed_everything(cfg.get("seed", 42))
# Use any ML library here.
score = 0.74
pcq.log(epoch=0, eval_score=score)
pcq.save_all(
history=[{"epoch": 0, "eval_score": score}],
status="completed",
artifacts={"model": "model.pkl"},
)
중레벨 — Lightning 스타일 Experiment
import pcq
from pcq import Experiment
class MyExp(Experiment):
def build_dataset(self, split): return pcq.examples.datasets.fake(num_samples=128)
def build_model(self): return pcq.examples.models.small_cnn(3, 10)
def build_loss(self): return pcq.loss.cross_entropy()
def build_optimizer(self, params): return pcq.examples.optim.adamw(params, lr=1e-3)
def training_step(self, batch):
# 반환: (loss_tensor, metrics_dict)
# loss_tensor 는 backward 용 grad 살아있는 tensor, metrics 는 logging 전용.
x, y = batch
logits = self.model(x)
loss = self.loss_fn(logits, y)
return loss, {"acc": pcq.metric.accuracy(logits, y).item()}
def eval_step(self, batch):
# 반환: metrics_dict (backward 없음)
x, y = batch
logits = self.model(x)
loss = self.loss_fn(logits, y)
return {"loss": loss.item(), "acc": pcq.metric.accuracy(logits, y).item()}
MyExp().fit() # accelerate 자동 감지, 5종 아티팩트 저장
고레벨 — preset + atom override
import pcq
# Case A: preset 한 줄
pcq.Trainer(preset="vision/cifar10_smallcnn_baseline").fit()
# Case B: preset + atom override
pcq.Trainer(
preset="vision/cifar10_smallcnn_baseline",
sched_factory=lambda o: pcq.examples.sched.cosine(o, T_max=20, warmup=1000),
).fit()
# Case C: preset 없이 atom 이름으로
pcq.Trainer(task="classification", dataset="fake", model="mlp").fit()
cq.yaml 통합
cq worker 가 cq.yaml 의 cmd 를 실행하면서 inline configs 를 CQ_CONFIG_JSON
환경변수에 JSON 파일 경로로 전달합니다. 라이브러리는 이 컨트랙트만 알고
있고, cq 의 Hub/Drive 를 직접 호출하지 않습니다.
# examples/cq.yaml
name: cq-python-smoke
cmd: uv run python examples/train.py
configs:
output_dir: output
epochs: 2
batch_size: 32
lr: 0.001
seed: 42
metrics:
- epoch
- train_loss
- train_acc
- eval_loss
- eval_acc
artifacts:
- output/
# examples/train.py — 9 줄
import pcq
cfg = pcq.config()
pcq.seed_everything(cfg["seed"])
pcq.Trainer(task="classification", dataset="fake", model="mlp", cfg=cfg).fit()
Structured cq.yaml (v1.15+)
기존 list-style metrics 는 영구 호환. agent 가 풍부한 메타데이터를 원할 때
dict-style metrics: 와 신규 inputs: 섹션을 사용한다. pcq 은 cq URI 를
opaque string 으로 취급한다 — parse / fetch 는 CQ service 의 책임.
inputs: 섹션 — dataset / input identity
inputs:
dataset:
name: dental
version: v12
uri: cq://datasets/dental/v12
split: train-val-2026-05-01
sha256: "abc123..."
metrics: dict-style — 각 metric 의 schema
# legacy (영구 호환)
metrics:
- eval_iou
- eval_loss
# v1.15+ structured (agent-friendly)
metrics:
eval_iou:
mode: max
split: val
aggregation: macro
sample_count: 1240
eval_loss:
mode: min
split: val
pcq validate 가 dict-style 일 때 추가 gate:
metric_schema_complete/metric_schema_mode/metric_schema_mode_value— 각 metric 의mode필드가min/max인지monitor_in_metric_schema/monitor_mode_consistency—configs.monitor가 schema key 인지 +configs.mode와 일치하는지inputs_declared/input_identity— inputs 섹션의 각 항목에name필드가 있는지
pcq inspect --json 출력의 cq_yaml 에 metrics_schema 와 inputs 가
포함된다 (둘 다 미사용이면 출력에서 생략).
RunRecord — Single Source of Truth (v1.16+)
run_record.json 은 한 실험 run 의 모든 evidence 를 담은 SSOT. CQ service 가
비교 / lineage / 재현성에 사용한다.
{
"schema_version": 1,
"run": {"id": "run_20260506_120000_abc", "status": "completed", "...": "..."},
"execution": {"cmd": "...", "config_path": "cq.yaml"},
"source": {"git_sha": "...", "dirty": false},
"environment": {
"python": "3.12.10",
"platform": "Darwin-arm64",
"lockfile": "uv.lock",
"lockfile_sha256": "..."
},
"inputs": {"dataset": {"name": "dental", "uri": "cq://...", "...": "..."}},
"metrics": {
"declared": [{"name": "eval_iou", "mode": "max", "split": "val"}],
"history_path": "metrics.json"
},
"artifacts": [{"path": "model.pt", "sha256": "...", "size_bytes": 0}],
"summary": {"target_metric": "eval_iou", "best": {"epoch": 12}},
"agent": {"plan_id": "exp-001", "recipe": "vision/seg/voc_unet"},
"validation": {"status": "pass", "report_path": "validation_report.json"}
}
자동 생성 경로
- Trainer / Experiment:
fit()끝나면 자동 작성. - Contract script:
pcq.save_all(history=[...])가 자동 finalize 포함 (opt-out:finalize=False). - 명시 호출:
pcq.finalize_run(history=[...])또는 CLIpcq finalize. - Post-run validation:
pcq validate-run [OUTPUT_DIR].
Source / Environment Snapshot
source.git_sha—git rev-parse HEAD(자동).source.dirty—git status --porcelain비어있지 않으면 true.source.patch_sha256,source.changed_files—cfg["record_patch"]: true시 opt-in.environment.python—sys.version.environment.platform—system + machine.environment.lockfile_sha256—uv.lock/poetry.lock/Pipfile.lock자동 감지.
CQ URI 는 opaque
inputs.dataset.uri: cq://datasets/... 같은 CQ-aware URI 는 pcq 이 parse / fetch
하지 않는다. CQ service 가 dataset fetch 를 담당. pcq 은 URI 를 string 그대로
record.
CLI
pcq finalize [OUTPUT_DIR] # run_record.json + validation_report.json 작성
pcq validate-run [OUTPUT_DIR] # post-run gates
# - manifest sha256 round-trip
# - metrics well-formed
# - run_summary best/last consistent
# - run_record completeness
Experiment.fit() / pcq.save_all() 사용 시 자동 — 외부 trigger 로 재생성 시에만
명시 호출.
ResolvedConfig — Single Source of Truth (v2.2+)
cq.yaml + CQ_CONFIG_JSON env 를 한 번 해석한 단일 view. inspect,
validate, finalize_run, RunRecord 가 모두 같은 resolver 를 거쳐 cq.yaml 해석
일관성을 보장한다.
import pcq
rc = pcq.resolve_project(path=".")
print(rc.cfg) # configs section (cq.yaml + env merged, env wins)
print(rc.declared_metrics) # always list[str], list/dict-style 둘 다 정규화
print(rc.metrics_schema) # dict-style metrics (mode/split/...) if present
print(rc.inputs) # opaque dict (cq URI 는 그대로 보존)
print(rc.output_dir) # absolute Path, project_root-rooted, mkdir-safe
CLI:
pcq resolve --json
cwd 의존 제거: resolve_project() 인자 없이 호출 시 cwd 기준 ancestor walk-up
(8 levels max, .git / pyproject.toml 만나면 stop). agent 가 어디서 실행하든
같은 cq.yaml 해석.
명시적 우선순위: CQ_CONFIG_JSON 의 cfg 가 cq.yaml.configs 위에 merge —
env 가 동일 키를 override.
Run Comparison & Description (v1.17+)
agent 가 RunRecord 만으로 다음 실험을 결정할 수 있는 read-side 도구. side-effect 없음.
pcq describe-run — compact run summary
pcq describe-run output/ --json
{
"schema_version": 1,
"run_id": "run_20260506_120000_abc",
"status": "completed",
"target_metric": "eval_iou",
"mode": "max",
"best": {"epoch": 4, "value": 0.78, "checkpoint": "best.ckpt"},
"best_value": 0.78,
"best_epoch": 4,
"last": {"epoch": 4, "value": 0.78, "checkpoint": "last.ckpt"},
"last_value": 0.78,
"last_epoch": 4,
"epochs_completed": 5,
"python": "3.12.10",
"platform": "Darwin-arm64",
"metrics_declared": [{"name": "eval_iou", "mode": "max"}],
"artifacts": [{"path": "model.pt", "kind": "model"}],
"artifacts_summary": {"model": 1, "checkpoint": 2, "metrics": 1, "summary": 1},
"plan_id": "plan-b-001",
"recipe": "improved",
"validation_status": "pass",
"reproducibility_evidence": {
"source": {"git_sha": "...", "dirty": false},
"environment": {"python": "3.12.10", "lockfile": "uv.lock"},
"config": {"seed": 42, "strictness": 3}
},
"decision_facts": {
"run_completed": true,
"validation_passed": true,
"has_best": true,
"artifact_count": 4
}
}
output/ 에 run_record.json 이 없으면 status: "no_record" 로 응답 (rc=0).
describe-run 은 다음 실험을 추천하지 않습니다. agent 가 판단할 수 있는
status / metric / artifact / validation / reproducibility facts 만 제공합니다.
pcq compare-runs A B — diff two runs
pcq compare-runs run_a/ run_b/ --json
{
"schema_version": 1,
"a_run_id": "run_20260505_160645_a54fdc",
"b_run_id": "run_20260505_160645_ccf92a",
"target_metric": "eval_iou",
"a_target_metric": "eval_iou",
"b_target_metric": "eval_iou",
"mode": "max",
"best": {"a": 0.66, "b": 0.78, "delta": 0.12, "direction": "improved"},
"metric_delta": 0.12,
"metric_direction": "improved",
"last": {"a": 0.63, "b": 0.76, "delta": 0.13, "direction": "improved"},
"config_changes": [
{"key": "_overrides_keys", "a": ["lr"], "b": ["batch_size", "lr"]},
{"key": "recipe", "a": "baseline", "b": "improved"}
],
"validation": {"a": "pass", "b": "pass", "same": true},
"artifacts": {"a_count": 4, "b_count": 5},
"source": {"same_git_sha": false, "same_cq_yaml_sha256": false},
"decision_facts": {
"comparable": true,
"same_target_metric": true,
"best_improved": true,
"candidate_validated": true,
"config_changed": true,
"source_changed": true
},
"a_status": "completed",
"b_status": "completed"
}
metric_direction 은 metrics.declared[].mode (없으면 min) 를 보고 결정:
| mode | delta < 0 | delta == 0 | delta > 0 |
|---|---|---|---|
max |
regressed | tied | improved |
min |
improved | tied | regressed |
compare-runs 도 추천하지 않습니다. agent 가 다음 실험을 고를 수 있도록 metric,
trajectory, config/input/source/artifact/validation/failure 차이와
decision_facts 만 제공합니다.
A/B 인자는 run_record.json 파일 직접 또는 output 디렉토리 둘 다 수용.
Failure Classifier
run_summary.json.failure.category 가 자동 분류되어 agent 가 다음 행동 결정:
| category | 처방 예시 |
|---|---|
oom |
batch_size 줄이기, gradient checkpointing |
nan_loss |
lr 줄이기 / gradient clip 적용 |
dataset_shape |
resize / collate_fn 점검 |
dataset_missing |
input identity / 데이터셋 pull 확인 |
missing_dependency |
uv add ... |
label_contract |
ignore_index / label range 확인 |
loss_contract |
loss signature / shape contract |
metric_contract |
declared metric vs emit mismatch |
timeout |
timeout_sec 늘리기 / 데이터 캐시 |
distributed_write_race |
manifest 쓰기 race — rank 분리 |
config_error |
CQ_CONFIG_JSON / cfg key 확인 |
unknown_exception |
logs 직접 확인 |
명시 카테고리(non-unknown_exception)가 이미 있으면 보존, 없거나 unknown 이면
failure.message 를 휴리스틱으로 분류.
Lineage Tracking (v1.18+)
agent 가 multi-run 진화를 추적하기 위한 RunRecord parent chain. RunRecord 의
run.parent_run_id + run.parent_run_path 두 필드로 연결한다 — semantic id
(검증) + path string (resolution).
Plan-driven (agent path)
ExperimentPlan 에 parent_run_id + parent_run_path 추가:
{
"schema_version": 1,
"id": "exp-005",
"intent": "Tighten regularization",
"base": {"preset": "vision/seg/voc_unet"},
"parent_run_id": "run_20260506_120000_abc",
"parent_run_path": "../run_004/output",
"changes": [
{"op": "set_config", "key": "weight_decay", "value": 5e-4}
]
}
pcq apply-plan 이 자동으로 cq.yaml.configs._parent_run_id /
_parent_run_path 를 주입. 다음 fit() / save_all() 종료 시 finalize_run 이
RunRecord.run.parent_run_id / parent_run_path 에 기록한다.
Script path (explicit)
pcq.save_all(
history=...,
parent_run_id="run_20260506_120000_abc",
parent_run_path="../run_004/output",
)
또는 cq.yaml configs 에 직접:
configs:
_parent_run_id: run_20260506_120000_abc
_parent_run_path: ../run_004/output
Lineage 조회
pcq lineage output/ --json
{
"schema_version": 1,
"chain": [
{"run_id": "current", "depth": 0, "best_value": 0.78, "target_metric": "eval_iou"},
{"run_id": "parent", "depth": 1, "best_value": 0.74, "target_metric": "eval_iou"},
{"run_id": "grandparent", "depth": 2, "best_value": 0.71, "target_metric": "eval_iou"}
],
"truncated": false,
"notes": []
}
compare-runs 도 lineage 인지 — 결과에 a_is_ancestor_of_b /
b_is_ancestor_of_a 필드가 포함된다.
안정성 보장
- 순환 감지: 같은
run_id가 다시 등장하면 chain 종료 + note 기록. - Missing parent:
parent_run_path가 가리키는 곳에run_record.json이 없으면 placeholder node 추가 + note. 빈 chain 반환하지 않음. - max_depth: default 100. 초과 시
truncated: true. - 상대 경로: child 의 output_dir 기준으로 해석되어 working tree 이동에 안전.
CQ URI 호환
parent_run_path 가 cq://... URI 여도 pcq 은 opaque string 으로 보존만
한다. pcq 의 lineage() 는 해당 노드를 follow 하지 않고 placeholder 추가
(note 에 "remote URI not followed"). URI resolve 책임은 CQ service.
Atom vs Contract Script — When To Use Which (v1.13)
pcq 은 두 가지 실험 작성 경로를 제공합니다. 어느 쪽이든 cq.yaml 위에서 동일하게 실행됩니다 — agent 는 두 경로를 모두 지원합니다.
Atom + RecipeSpec (PyTorch path)
실험 컴포넌트가 select / replace / validate / reuse 되어야 할 때.
import pcq
pcq.Trainer(
preset="vision/seg/voc_unet",
sched=pcq.sched_ref("cosine", {"T_max": 80, "warmup": 1000}),
).fit()
apply-plan 의 set_atom 으로 atom 단위 swap 가능. validate 가 ignore_index /
in_channels / extras 일관성 검사. project-local atom 등록 가능.
Contract Script (any framework)
framework 가 자체 training flow 를 갖고 있을 때 (HF Trainer, sklearn, XGBoost, TabPFN, PyCaret, custom code).
import pcq
from sklearn.ensemble import RandomForestClassifier
cfg = pcq.config()
out = pcq.output_dir()
model = RandomForestClassifier(n_estimators=cfg["n_estimators"])
model.fit(X_tr, y_tr)
acc = model.score(X_te, y_te)
pcq.log(epoch=0, eval_acc=acc)
pcq.save_all(
history=[{"epoch": 0, "eval_acc": acc}],
artifacts={"model": "model.pkl"},
)
agent 는 set_config 로만 hyperparameter 변경 (set_atom 거부). atom 시스템은
경유하지 않음 — framework 자체가 모델/loss/optim 을 책임.
Decision tree
컴포넌트 swap 이 실험 핵심?
├─ YES → Atom + RecipeSpec (PyTorch)
└─ NO, framework 자체로 training flow
└─ Contract Script (any library)
pcq init-experiment --style script|trainer|experiment 로 시작.
examples/contract_numpy.py 는 core dependency 만으로
항상 실행되는 framework-neutral reference 이고,
examples/contract_sklearn.py 는 sklearn-iris
optional reference 입니다.
확장 — Project-Local Atoms (v1.12+)
포지셔닝 (v2.7): pcq 의 built-in atom 들 (
pcq.examples.{models,datasets,optim,sched},pcq.loss,pcq.metric) 은 reference examples — contract 검증 + 온보딩 + smoke baseline 용 예시 구현입니다. production catalog 가 아닙니다. 실제 연구 atom 은 project-localatoms/디렉토리에 등록.pcq.{models,datasets,optim,sched}는pcq.examples.*를 다시 내보내는 v2 compatibility facade 입니다. AtomSpec 의role="reference_example"필드와pcq atoms list인간 출력의[reference example]태그로도 구분됩니다.
실제 실험은 project-local atom 으로 작성:
# 1. atom skeleton 생성
pcq atoms scaffold model dental_unet
# → atoms/models.py 생성, @pcq.register_model + meta 채워둠
# 2. implementation 채우기 (수동 또는 agent)
# atoms/models.py 편집
# 3. 검증
pcq atoms validate-local # metadata + contract 완전성
pcq atoms smoke model dental_unet --load-project . # forward 1-step 검증
# 4. recipe 에서 사용
pcq.model_ref("dental_unet", {"num_classes": 4})
init-experiment 가 cq_atoms.py + atoms/__init__.py 를 함께 생성합니다.
train.py 는 자동으로 cq_atoms 를 import → 추가 작업 없이 atom 등록.
pcq inspect 는 기본적으로 project atom 을 import 하지 않는 read-only
모드입니다. project atom 까지 registry view 에 포함하려면 명시적으로
--load-project-atoms 를 사용합니다.
pcq inspect . --load-project-atoms --json
pcq atoms list --source project --json # project atom 만
pcq atoms list --source builtin --json # builtin 만
pcq atoms list --load-project /path/to/project --json
Atom Sources
| Source | 위치 | 추가 정책 | role (v2.4) |
|---|---|---|---|
builtin |
pcq 내부 |
추가 X — contract example only | reference_example |
project |
cq_atoms.py, atoms/*.py |
사용자/agent 자유 작성 — primary path | user |
generated |
agent 실험 루프 산출 | project atom 과 동일 메커니즘 | user |
external |
외부 패키지 등록 | (예약) | user |
role 은 v2.4 추가 메타데이터. pcq atoms list --json 결과의 각 entry 에
포함되며, builtin atom 이 production catalog 가 아니라 contract example 임을
명시합니다.
확장 (atoms / recipes)
pcq 은 두 레이어로 확장합니다.
Atom — Python 함수
pcq 이 제공하는 계약 예제(pcq.examples.models, pcq.examples.datasets,
pcq.examples.optim, pcq.examples.sched)와 helper atom (pcq.loss,
pcq.metric)을 직접 호출하거나 사용자 코드에 자기 함수를 작성. 직접 사용 시
등록 불필요:
import pcq
my_model = pcq.examples.models.small_cnn(3, 10)
dataset = pcq.examples.datasets.fake(num_samples=32)
optim = pcq.examples.optim.adamw(my_model.parameters(), lr=1e-3)
acc = pcq.metric.accuracy(logits, y)
pcq.{models,datasets,optim,sched} 는 v2 호환용 facade 입니다. 신규 코드와
문서는 pcq.examples.* 또는 project-local atom 을 우선 사용합니다.
String-name 등록 (Trainer(model="name") 용)
string lookup 을 쓰려면 registry 에 등록:
import pcq
# 함수 형태
pcq.register_model("vit_b16", lambda: my_vit_b16(num_classes=10))
pcq.register_dataset("my_data", lambda split: MyDataset(train=(split == "train")))
pcq.register_metric("f1", lambda l, y: my_f1_impl(l, y))
# 데코레이터 형태
@pcq.register_model("custom_resnet")
def factory():
return torchvision.models.resnet50(num_classes=100)
pcq.Trainer(model="vit_b16", dataset="my_data").fit()
pcq.Trainer.list_models() # 등록된 모델
pcq.Trainer.list_datasets() # 등록된 데이터셋
pcq.Trainer.list_metrics() # 등록된 메트릭
pcq.Trainer.list_presets() # 등록된 recipe
내장 atom 들은 모듈 import 시 자동 등록됩니다.
Atom Registry — Metadata-Aware (v1.8+)
atom 등록 시 meta=... 로 ParamSpec / contracts / extras 를 함께 선언하면
agent 가 검증·검색할 수 있습니다:
import pcq
pcq.register_loss(
"boundary_dice",
factory=lambda smooth=1.0: BoundaryDiceLoss(smooth=smooth),
meta={
"tasks": ["segmentation"],
"params": {"smooth": {"type": "float", "default": 1.0, "min": 0.0}},
"input_contract": {"logits": ["B","C","H","W"], "target": ["B","H","W"]},
"label_contract": {"target_dtype": "int64", "ignore_index_param": "ignore_index"},
},
)
기존 단순 형태 (pcq.register_X("name", factory)) 도 그대로 — metadata_status="inferred"
로 wrap. v1.8 에서 cross_entropy / unet / fake_seg / voc_seg / iou 가 explicit.
AtomRef — Agent-Operable References (v1.8+)
agent 는 직렬화 가능한 ref 로 atom 을 사용할 수 있습니다:
ref = pcq.loss_ref("cross_entropy", {"ignore_index": -1})
# ref.to_dict() → {"kind": "loss", "name": "cross_entropy", "params": {"ignore_index": -1}}
CLI 로 카탈로그·검증:
pcq atoms list --json
pcq atoms list --kind loss --json
pcq atoms show loss cross_entropy --json
pcq atoms validate-ref ref.json --json
RecipeSpec — Metadata-First Recipes (v1.8+)
vision/seg/* recipe 는 v1.8 부터 RecipeSpec 기반:
from pcq.agent.schema import RecipeSpec
import pcq
SPEC = RecipeSpec(
name="vision/seg/my_recipe",
task="segmentation",
metrics=["epoch", "train_loss", "eval_iou"],
monitor_candidates=[{"name": "eval_iou", "mode": "max"}],
requires_extras=["vision"],
smoke_safe=False,
atoms={
"model": pcq.model_ref("unet", {"num_classes": 21}),
"dataset_train": pcq.dataset_ref("voc_seg", {"image_set": "train"}),
"dataset_eval": pcq.dataset_ref("voc_seg", {"image_set": "val"}),
"loss": pcq.loss_ref("cross_entropy", {"ignore_index": -1}),
"optim": pcq.optim_ref("adamw", {"lr": 1e-3}),
"sched": pcq.sched_ref("cosine", {"T_max": 50, "warmup": 500}),
},
defaults={"epochs": 50, "batch_size": 16},
)
def my_recipe() -> dict:
return SPEC.build()
기존 dict recipe (vision/fake_smoke, vision/cifar10_*, nlp/* 등) 은 그대로 호환.
Recipe — atom 조합의 named alias
src/pcq/recipes/<group>/<name>.py 에 함수만 작성하면 Trainer.list_presets() 이
pkgutil 로 자동 발견. 데코레이터 등록 불필요:
# src/pcq/recipes/vision/my_recipe.py
from pcq import datasets, loss, optim
from pcq.examples import models as example_models
def my_recipe() -> dict:
return {
"model": example_models.small_cnn(3, 10),
"dataset_train": lambda _split: datasets.cifar10("data", train=True, download=True),
"dataset_eval": lambda _split: datasets.cifar10("data", train=False, download=True),
"loss": loss.cross_entropy(),
"optim_factory": lambda p: optim.adamw(p, lr=1e-3),
"epochs": 30, "batch_size": 128,
}
Contract Behavior (v1.6)
agent-operability 를 위한 5가지 contract gap 을 v1.6 에서 닫았습니다. docs/AGENT_OPERABILITY.md §"Phase A: Fix Current Contract Gaps" 참조.
Declared Metrics 자동 로드
pcq.log() 는 다음 우선순위로 declared metrics 를 검증합니다:
CQ_DECLARED_METRICS환경변수 (콤마 구분).CQ_CONFIG_JSON이 가리키는 JSON 파일의_metrics_declared키 (자동).
이전엔 사용자가 직접 env 를 설정하거나 cfg 인자를 줘야 했지만, v1.6 부터
pcq.log() 가 CQ_CONFIG_JSON 을 자동으로 1회 읽어 캐시합니다. 이미
cq.yaml.metrics 에 메트릭을 선언했다면 추가 설정 불필요.
cross_entropy(ignore_index=...)
pcq.loss.cross_entropy(ignore_index=-1) # segmentation: void/-1 무시
pcq.loss.cross_entropy(weight=torch.tensor([0.1, 0.5, 1.0])) # 클래스 가중
VOC voc_seg 가 void(255) 를 -1 로 변환하므로 voc_unet recipe 는
ignore_index=-1 로 학습합니다.
voc_seg(image_size=...)
torchvision.VOCSegmentation 은 가변 크기 PIL 이미지를 반환하므로 default
DataLoader collate 가 stack 못 합니다. v1.6 부터 image_size=256 (default) 로
image 와 mask 를 동기 리사이즈합니다 (image=bilinear, mask=nearest).
Best Checkpoint Monitor — 사전 검증
fit() 시작 시 monitor key 가 declared metrics 안에 없으면 stderr 에 즉시
경고합니다. agent/사용자가 학습 시작 전에 best.ckpt 가 안 만들어질 수 있다는
사실을 인지할 수 있습니다.
Multi-process Safety (accelerate)
accelerate 활성화 시 모든 IO (stdout @key=value 메트릭, checkpoint,
최종 artifact) 는 main process 에서만 수행합니다. multi-GPU 환경에서 동일
파일에 race write 발생 안 함. epoch 종료 후 wait_for_everyone() 으로
process 동기화.
Recipe 카탈로그 (v1.4)
| Recipe | dataset × model | dep |
|---|---|---|
vision/fake_smoke |
fake × mlp | torch only |
vision/mnist_mlp |
MNIST × mlp | + torchvision |
vision/cifar10_smallcnn_baseline |
CIFAR-10 × small_cnn | + torchvision |
vision/cifar10_resnet18 |
CIFAR-10 × ResNet-18 | + torchvision |
vision/seg/fake_seg_smoke |
fake_seg × UNet | torch only |
vision/seg/voc_unet |
Pascal VOC × UNet | + torchvision |
nlp/fake_text_classifier |
fake_text × Embed+Mean+Linear | torch only |
pcq.Trainer.list_presets() 로 전체 목록 확인. pcq.Trainer.print_recipe(name)
으로 atom 조합 검사 가능. Recipe 모듈 경로는 임의 깊이 nested group 을 지원합니다
(vision/seg/<name> 처럼).
메트릭 schema 경고
cq.yaml.metrics 에 선언되지 않은 key 를 pcq.log() 로 출력하면 첫 1회
stderr 경고와 종료 시 누적 요약을 출력합니다. CI 에서는 pcq.log(strict=True)
로 즉시 실패하게 만들 수 있습니다.
분산 학습
pcq[dist] 로 accelerate 를 설치하면 Experiment.fit() 이 자동으로
multi-GPU/DDP/FSDP 경로로 분기합니다.
Device 우선순위: cfg["device"] (명시) > CUDA > MPS (Apple Silicon) > CPU.
cfg["device"] 를 명시하면 accelerate 분기를 우회합니다 (사용자가 명시한
device 를 accelerate 가 덮어쓰지 않도록). multi-GPU 를 원하면 device 를
명시하지 않고 pcq[dist] 만 설치하세요.
configs:
device: cpu # accelerate 우회 + 강제 CPU
Resume
configs:
resume_from: output/last.ckpt # 명시적 path
# 또는
resume: true # 자동: output_dir/last.ckpt 발견 시 resume, 없으면 fresh
resume_from 이 명시적 우선. resume: true 만 있으면 output_dir 에서
last.ckpt 를 찾아 자동 resume (없으면 silent fresh start). resume_from
명시 시 그 path 가 없으면 여전히 FileNotFoundError 가 발생합니다 (auto fallback X).
Best Checkpoint Monitor
기본 best.ckpt 는 eval_loss 최소 epoch 을 저장합니다. cfg 로 다른 메트릭/방향 지정:
configs:
monitor: eval_acc # history entry 키 (epoch 별 metrics)
mode: max # min | max
monitor key 가 metrics 에 없으면 stderr 1회 경고 후 best.ckpt 저장을
건너뜁니다 (last.ckpt 는 그대로 매 epoch 저장).
AMP + Gradient Accumulation
configs:
amp: true # autocast + GradScaler (cuda+fp16) 또는 autocast 만 (bf16/cpu)
amp_dtype: fp16 # fp16 | bf16
grad_accum: 4 # effective batch_size = batch_size * grad_accum
- fp16 + cuda:
torch.amp.GradScaler활성화 (overflow 방지) - bf16 또는 cpu/mps: autocast 만 사용 (GradScaler 불필요)
accelerate활성화 시 pcq 의 AMP 경로는 우회 (accelerate 가 처리)- grad_accum 은 마지막 batch 또는
accum_steps마다optimizer.step()실행
Early Stopping
monitor 인프라를 그대로 재사용. 개선 없는 epoch 이 patience 초과 시 중단:
configs:
monitor: eval_loss
mode: min
early_stop_patience: 5 # 5 epoch 무개선 → 중단
early_stop_min_delta: 0.001
early_stop_patience: 0(default) → 비활성화min_delta만큼 개선되어야 'improved' 로 카운트no_improve_count는 ckpt 에 저장 → resume 시 누적 카운트 복원- 중단 시
metrics.json에early_stopped_at_epoch기록
Metric Aggregation
기본은 batch 단위 단순 평균. variable batch size 환경 (마지막 drop_last=False) 에서 last-batch bias 가 신경 쓰이면 weighted_mean 사용:
configs:
metrics_aggregation: weighted_mean # batch_size 가중 평균 (default: mean)
정확한 sample-weighted aggregation 이 필요하면 pcq.metric.stateful 의 클래스
사용 (v1.3 은 사용자가 직접 update/compute, v1.4 에서 Experiment 자동 통합 예정):
acc = pcq.metric.stateful.Accuracy()
for batch in loader:
x, y = batch
acc.update(model(x), y)
print(acc.compute()) # 전체 sample 기준 정확도
Artifacts
fit() 종료 시 output_dir 에 다음 파일들이 생성됩니다:
| 파일 | 설명 |
|---|---|
model.pt |
최종 model.state_dict() |
config.json |
정규화된 cfg + git SHA + pcq version + _recipe/_overrides |
metrics.json |
{"history": [...]} epoch 별 history |
run_summary.json |
best/last/target/provenance 요약 |
last.ckpt |
매 epoch 저장 (resume 용) |
best.ckpt |
monitor 기준 best epoch (default: eval_loss min) |
manifest.json |
output 파일 인덱스 — schema v2 (sha256 + size_bytes + created_at) |
Manifest schema v2 (v1.14+)
v1.14 부터 manifest.json 은 단순 file list 가 아니라 artifact evidence
를 기록합니다. 각 entry 는 sha256, size_bytes, created_at 을 포함하므로
CQ worker / agent 가 artifact 무결성을 round-trip 검증할 수 있습니다.
{
"schema_version": 2,
"files": [
{
"path": "model.pt",
"kind": "weights",
"sha256": "8bb2ec07...",
"size_bytes": 18423920,
"created_at": "2026-05-05T10:58:00Z"
}
]
}
대형 weight 가 많아 sha256 비용이 부담될 때는 cfg 에서 opt-out 가능 (schema v1 fallback — path/kind 만):
configs:
manifest_checksums: false
pcq validate 의 post-run gate manifest_evidence 가 manifest entries
가 실제 file 을 가리키고 sha256 이 일치하는지 검증합니다. v1 legacy manifest
는 file 존재 검증만 수행합니다.
자세한 표준은 docs/RUN_RECORD.md를 참고하세요.
config.json 의 provenance 필드 (v1.4):
| 필드 | 의미 |
|---|---|
_git_sha |
학습 시점 HEAD commit SHA |
_pcq_version |
사용된 pcq 버전 |
_recipe |
base preset 이름 (없으면 atom-only 모드) |
_overrides |
사용자가 override 한 atom 키 정렬 목록 |
Recipe Acceptance Framework (v1.4)
모든 등록된 recipe 는 SPEC §"Recipe Acceptance Criteria" 7항목을 자동 검증
합니다. 새 recipe 를 catalog 에 추가하면 tests/test_acceptance.py 의 parametrize
가 자동으로 검증 항목을 추가합니다.
from pcq.testing import recipe_smoke, list_failures
# 단일 recipe 검증
report = recipe_smoke("vision/cifar10_smallcnn_baseline")
print(report)
# Recipe: vision/cifar10_smallcnn_baseline
# Status: PASS
# [PASS] import: recipe module importable without training
# [PASS] inspect: recipe() returned dict (12 keys)
# [PASS] smoke_path: using 2 override(s): ['dataset_eval', 'dataset_train']
# [PASS] fit_smoke: one epoch completed
# [PASS] declared_metrics: all 5 emitted
# [PASS] artifacts: all 5 present
# [PASS] resume: resume from last.ckpt succeeded
# 모든 recipe 일괄 검증 — 실패한 것만
fails = list_failures()
Recipe 작성자는 metadata 키로 acceptance 동작을 제어합니다:
def my_recipe() -> dict:
return {
# 기존 atom 키
"model": ..., "dataset_train": ..., "loss": ..., "optim_factory": ...,
# v1.4 옵션 metadata
"metrics": ["epoch", "train_loss", "eval_acc"],
"requires_extras": ["vision"], # pcq[vision] for torchvision
"smoke_safe": False, # 외부 dataset/network 필요
"smoke_overrides": { # acceptance 가 substitute 할 atom
"dataset_train": lambda _split: pcq.datasets.fake(...),
"dataset_eval": lambda _split: pcq.datasets.fake(...),
},
}
smoke_safe=True→ recipe atoms 그대로 1-epoch 학습smoke_safe=False+smoke_overrides→ override 로 atom 치환 후 학습smoke_safe=False+ overrides 없음 → acceptance failmetrics비어있으면 declared metrics 검증 skiprequires_extras의 패키지 미설치 시 해당 recipe 는 skip (fail X)
Agent-Native Helpers (v1.4)
VISION §"Agent-Native Future" 시작점. agent 가 recipe 를 선택·diff·검증하기 위한 inspection API. 모두 학습 부작용 없음:
import pcq
# Recipe metadata — atom 조합 + 선언된 metrics + extras 요구사항
pcq.recipe_meta("vision/seg/fake_seg_smoke")
# {'name': 'vision/seg/fake_seg_smoke', 'task': 'segmentation',
# 'declared_metrics': ['epoch', 'train_loss', 'train_iou', ...],
# 'requires_extras': [], 'atoms': {'model': '_UNet (instance)', ...}, ...}
# Recipe diff — 두 baseline 의 atom/설정 비교
pcq.diff_recipes("vision/cifar10_smallcnn_baseline", "vision/cifar10_resnet18")
# Catalog 둘러보기
metas = pcq.agent.list_meta()
for m in metas:
print(m["name"], "→", m["task"], "extras:", m["requires_extras"])
# Dry run — 조립 plan 만 보여주고 학습 X
plan = pcq.Trainer(
preset="vision/cifar10_resnet18",
sched_factory=lambda o: pcq.sched.cosine(o, T_max=10),
).dry_run()
print(plan["preset"], plan["overrides"], plan["expected_artifacts"])
CLI (Agent JSON Interface, v1.7+)
pcq 은 agent 가 Python import 없이 사용할 수 있는 JSON CLI 를 제공합니다.
pcq resolve . --json # ResolvedConfig JSON
pcq resolve --cq-yaml ./cq.yaml --json # explicit cq.yaml
pcq inspect . --json # ProjectInspection JSON (read-only)
pcq inspect . --load-project-atoms --json # opt-in project atom import
pcq recipe-meta vision/fake_smoke --json # RecipeMeta JSON
pcq dry-run . --json # 조립된 plan (학습 X)
pcq validate . --strictness 2 --json # ValidationReport (fail → exit 1)
pcq validate-run output --strictness 3 --json
pcq summarize-run output/ --json # RunSummary JSON
pcq run --path . --json # execute cq.yaml.cmd; pure JSON envelope
pcq init-experiment --style script --output ./tabular-exp --json
pcq agent install --target codex --path ./tabular-exp --json
pcq agent status --target codex --path ./tabular-exp --json
학습 후 output/run_summary.json 이 자동 생성되며 summarize-run 이 그대로
읽습니다. 파일이 없으면 metrics.json+config.json 에서 합성합니다.
모든 JSON 출력은 schema_version 필드를 포함합니다. 핵심 surface 는
JSON Contracts 와
pcq.agent.json_contracts.JSON_CONTRACTS 에서 최소 안정 필드를 고정합니다.
검증 강도는 Strictness Evidence Matrix 와
pcq.agent.strictness.STRICTNESS_EVIDENCE_MATRIX 에서 레벨별 필수 evidence 를
고정합니다.
pcq run --json 은
stdout 에 envelope JSON 만 출력하고, child process stdout/stderr 는
.pcq/run_stdout.log / .pcq/run_stderr.log 로 캡처한 뒤 JSON 의
stdout_path, stderr_path, stdout_tail, stderr_tail 로 요약합니다.
v1.x 동안 additive 변경만 보장되며, exit code 는 0 (성공) / 1 (실패·검증 fail)
/ 2 (argparse error) 입니다.
| Command | 무엇을 하나 | exit |
|---|---|---|
resolve [--cq-yaml PATH] |
cq.yaml + env 를 단일 read-only ResolvedConfig 로 해석 | 0 |
inspect [--load-project-atoms] |
cq.yaml + entrypoint + recipe 카탈로그 + outputs 상태를 한 번에 | 1 if path missing/import error |
recipe-meta |
단일 recipe 의 atom 요약 + declared metrics | 1 if recipe unknown |
dry-run |
entrypoint 의 preset 으로 Trainer 조립 plan | 1 if no preset |
validate [--plan PLAN.json] [--strictness 0..4] |
static + recipe contract + strictness evidence validation | 1 if blocking fail |
summarize-run |
완료된 output 의 best/last/provenance 요약 | 1 if status=failed |
run |
cq.yaml.cmd 실행 + CQ_CONFIG_JSON 자동 wiring; --json 은 pure JSON envelope |
cmd exit code |
init-experiment |
`--style trainer | experiment |
agent install |
Codex/Claude instruction + skill runtime assets 설치 | 1 if invalid |
agent status |
Codex/Claude instruction + skill runtime assets 상태 검사 (read-only) | 1 if invalid |
apply-plan |
ExperimentPlan JSON 을 cq.yaml configs 에 안전하게 적용 (v1.10+) | 1 if rejected |
atoms {list,show,scaffold,validate-local,smoke,validate-ref} |
atom registry 검사 / project atom scaffold (v1.8+, v1.12+) | 1 if invalid |
| `finalize [--project-root PATH] [--status completed | failed | partial]` |
validate-run [--strictness 0..4] |
post-run gates (manifest evidence + metrics + summary + strictness evidence) (v1.16+) | 1 if any gate fails |
describe-run |
compact RunRecord summary (v1.17+) | 1 if no run_record |
compare-runs A B |
두 RunRecord 의 metric / config / atom diff (v1.17+) | 1 if invalid record |
lineage [OUTPUT_DIR] [--max-depth N] |
parent_run_id chain 따라가며 ancestry 출력 (v1.18+) | 1 if no run_record |
Phase D — Agent Mutation (v1.10+)
agent 는 ExperimentPlan JSON 으로 실험을 구조적으로 수정한다.
# 1. 새 프로젝트 scaffold
pcq init-experiment --style trainer --preset vision/fake_smoke \
--output ./my-experiment \
--name dental-baseline
# 2. ExperimentPlan 작성 (LLM 또는 사람)
cat > plan.json <<'EOF'
{
"schema_version": 1,
"id": "exp-001",
"intent": "longer training",
"base": {"preset": "vision/fake_smoke"},
"target": {"metric": "eval_acc", "mode": "max"},
"changes": [
{"op": "set_config", "key": "epochs", "value": 80},
{"op": "set_atom", "atom": "loss", "name": "cross_entropy",
"params": {"ignore_index": -100}}
]
}
EOF
# 3. 검증 (apply 전)
pcq validate ./my-experiment --plan plan.json --json
# 4. 적용 (cq.yaml 만 수정, idempotent, provenance 자동 저장)
pcq apply-plan plan.json --path ./my-experiment --json
# 5. 학습
cd ./my-experiment && uv run python train.py
apply-plan 은 cq.yaml 의 configs 만 수정한다. train.py 와 recipes/local.py
는 사용자 영역 (수정하지 않음). provenance 는 .pcq/plans/<plan_id>.json 에 자동
저장 (plan + applied_at + operations).
지원 ChangeOp:
set_config—configs.<key> = <value>(v1.10+)set_atom—configs._overrides_data.<atom> = AtomRef.to_dict().Trainer.from_cfg(cfg)가 학습 시점에 deserialize.merge: true면 기존 params 와 병합 (v1.11+)set_dataset_transform— split-aware sugar forset_atommerge (v1.11+)
v1.11 추가: set_atom merge + set_dataset_transform
기존 atom 의 params 일부만 변경 (전체 ref 재명시 X):
{"op": "set_atom", "atom": "dataset_train", "name": "voc_seg",
"params": {"image_size": 384}, "merge": true}
dataset transform 전용 sugar:
{"op": "set_dataset_transform", "split": "train", "params": {"image_size": 384}}
→ 내부적으로 set_atom (merge=true) on dataset_train. dataset name 은 base
recipe SPEC.atoms 또는 기존 override 에서 자동 상속.
YAML Comment Preservation (v1.11+)
기본 cq.yaml writer 는 minimal — comment 를 보존하지 않는다 (rewrite). comment 및 인용/인덴트 형태를 살리려면:
uv add 'pcq[yaml]' # ruamel.yaml>=0.17 설치
설치 시 자동 감지 — read/write 가 round-trip 형태로 comment + 인용 + 인덴트 보존.
v1.12 (예정): set_smoke_override, custom_code_patch (gated).
Trainer.from_cfg(cfg) 가 cfg["preset"] + cfg["_overrides_data"] 를 자동
인식해 trainer 를 조립한다 (init-experiment 가 만든 train.py 의 1줄).
CI / Smoke
GitLab CI (/.gitlab-ci.yml)는 매 push/MR에서 3 stage 실행:
| Stage | 명령 | 목적 |
|---|---|---|
lint |
uv run ruff check src/ tests/ |
코드 스타일 |
test |
uv run pytest tests/ |
단위 + 통합 + acceptance |
smoke |
bash scripts/release-smoke.sh |
실제 cq.yaml 시뮬 + 아티팩트 검증 |
수동 검증:
bash scripts/release-smoke.sh
# 6단계: lint → pytest → recipe acceptance → CQ_CONFIG_JSON subprocess →
# artifacts/stdout/manifest/provenance 검증
scripts/release-smoke.sh는 release 태그 전 로컬에서도 실행 권장.
Status
pcq 은 stable v2.0 baseline 입니다. 안정화된 surface:
- Contract artifacts (run 당 6 개 표준 파일 — config.json / metrics.json / manifest.json (v2) / run_summary.json / run_record.json / validation_report.json)
- 두 가지 패턴 — Atom + Recipe (PyTorch) / Contract Script (any framework)
- 13 개 CLI subcommand (agent operability)
- RunRecord SSOT + lineage tracking
- 605 tests passing
v2.x 는 core API 변경보다 CQ service integration hooks 에 집중합니다. pcq 자체는 작은 surface 를 유지합니다.
Roadmap (v2.x)
- contract-script examples for Hugging Face Trainer / TabPFN / PyCaret / sklearn
- project-local atom validation and smoke checks 강화
- generated atom provenance and review workflow
- optional reference recipes for NLP / vision / tabular tasks
- CQ service integration contract 문서화 (post-finalize webhook 등)
License
Apache License 2.0. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pcq-3.0.0.tar.gz.
File metadata
- Download URL: pcq-3.0.0.tar.gz
- Upload date:
- Size: 432.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.16 {"installer":{"name":"uv","version":"0.9.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ba5510566107dbe77ce19ffcd0f4e92832cb65f66f3d419c453c44849c6f2a5d
|
|
| MD5 |
373deddd7800390dc4059f42feac8c1b
|
|
| BLAKE2b-256 |
ac5c6ddc70aee7185117df92a174efa1cd4a6de90d6973202e568a4891d06f86
|
File details
Details for the file pcq-3.0.0-py3-none-any.whl.
File metadata
- Download URL: pcq-3.0.0-py3-none-any.whl
- Upload date:
- Size: 192.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.16 {"installer":{"name":"uv","version":"0.9.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8228055b6d5902afd01e776453f083ee0b9ead4b48f552b99ba94682433c4e1e
|
|
| MD5 |
3d0da511fe6da95cdadc83cae826d797
|
|
| BLAKE2b-256 |
8645f63ef5633253b75a2319881a8a59c7551c693b074cdf9902f35feed5ce79
|