pcq 3.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. pcq/__init__.py +133 -0
  2. pcq/_registry.py +17 -0
  3. pcq/agent/__init__.py +264 -0
  4. pcq/agent/apply.py +601 -0
  5. pcq/agent/compare.py +631 -0
  6. pcq/agent/describe.py +363 -0
  7. pcq/agent/failure_classifier.py +57 -0
  8. pcq/agent/init.py +424 -0
  9. pcq/agent/inspect.py +423 -0
  10. pcq/agent/install.py +631 -0
  11. pcq/agent/json_contracts.py +373 -0
  12. pcq/agent/lineage.py +237 -0
  13. pcq/agent/plan.py +380 -0
  14. pcq/agent/resolver.py +400 -0
  15. pcq/agent/run_record.py +273 -0
  16. pcq/agent/scaffold.py +453 -0
  17. pcq/agent/schema.py +331 -0
  18. pcq/agent/smoke.py +260 -0
  19. pcq/agent/strictness.py +170 -0
  20. pcq/agent/summary.py +191 -0
  21. pcq/agent/validate.py +1260 -0
  22. pcq/agent/validate_run.py +711 -0
  23. pcq/agent/yaml_io.py +480 -0
  24. pcq/agent_assets/AGENTS.pcq.md +77 -0
  25. pcq/agent_assets/__init__.py +1 -0
  26. pcq/agent_assets/skills/pcq/SKILL.md +243 -0
  27. pcq/cli.py +1385 -0
  28. pcq/contract.py +1178 -0
  29. pcq/core.py +266 -0
  30. pcq/datasets.py +28 -0
  31. pcq/examples/__init__.py +53 -0
  32. pcq/examples/datasets.py +522 -0
  33. pcq/examples/models.py +397 -0
  34. pcq/examples/optim.py +52 -0
  35. pcq/examples/sched.py +77 -0
  36. pcq/experiment.py +557 -0
  37. pcq/loss.py +214 -0
  38. pcq/metric/__init__.py +35 -0
  39. pcq/metric/functional.py +237 -0
  40. pcq/metric/stateful.py +83 -0
  41. pcq/models.py +28 -0
  42. pcq/optim.py +13 -0
  43. pcq/recipes/__init__.py +1 -0
  44. pcq/recipes/nlp/__init__.py +1 -0
  45. pcq/recipes/nlp/fake_text_classifier.py +47 -0
  46. pcq/recipes/vision/__init__.py +1 -0
  47. pcq/recipes/vision/cifar10_resnet18.py +52 -0
  48. pcq/recipes/vision/cifar10_smallcnn_baseline.py +52 -0
  49. pcq/recipes/vision/fake_smoke.py +46 -0
  50. pcq/recipes/vision/mnist_mlp.py +56 -0
  51. pcq/recipes/vision/seg/__init__.py +1 -0
  52. pcq/recipes/vision/seg/fake_seg_smoke.py +46 -0
  53. pcq/recipes/vision/seg/voc_unet.py +67 -0
  54. pcq/registry/__init__.py +143 -0
  55. pcq/registry/loader.py +162 -0
  56. pcq/registry/spec.py +215 -0
  57. pcq/sched.py +13 -0
  58. pcq/testing.py +232 -0
  59. pcq/trainer.py +387 -0
  60. pcq-3.0.0.dist-info/METADATA +1385 -0
  61. pcq-3.0.0.dist-info/RECORD +64 -0
  62. pcq-3.0.0.dist-info/WHEEL +4 -0
  63. pcq-3.0.0.dist-info/entry_points.txt +2 -0
  64. pcq-3.0.0.dist-info/licenses/LICENSE +201 -0
pcq/__init__.py ADDED
@@ -0,0 +1,133 @@
1
+ """pcq — ML authoring library on top of cq.yaml runtime contract.
2
+
3
+ 이 패키지는 cq.yaml 런타임 계약(CQ_CONFIG_JSON, stdout @key=value, output_dir)을
4
+ 감싸는 편의 계층이다.
5
+
6
+ Note: cq.yaml / CQ_CONFIG_JSON / cq:// URI 스킴은 CQ Go service contract
7
+ specification 으로, pcq 라이브러리 이름과 무관하게 그대로 유지된다.
8
+ """
9
+ from pcq import _registry, agent, datasets, loss, metric, models, optim, sched, testing
10
+ # v2.7: examples namespace — reference example implementations live under
11
+ # pcq.examples.*. pcq.{models,datasets,optim,sched} remain compatibility facades.
12
+ from pcq import examples
13
+ from pcq.agent import (
14
+ ResolvedConfig,
15
+ RunContext,
16
+ compare_runs,
17
+ describe_run,
18
+ diff_recipes,
19
+ inspect_project,
20
+ list_meta,
21
+ recipe_meta,
22
+ resolve_project,
23
+ resolve_run_context,
24
+ summarize_run,
25
+ validate_project,
26
+ )
27
+ from pcq.contract import (
28
+ finalize_run,
29
+ save_all,
30
+ save_config_snapshot,
31
+ save_manifest,
32
+ save_metrics,
33
+ save_partial_run_record,
34
+ save_run_summary,
35
+ )
36
+ from pcq.core import config, input_dir, log, output_dir, seed_everything
37
+ from pcq.experiment import Experiment
38
+ from pcq.registry.spec import AtomRef, AtomSpec, ParamSpec
39
+ from pcq.trainer import Trainer
40
+
41
+ # 확장 API: Registry 함수/데코레이터 폼
42
+ register_model = _registry.models.register
43
+ register_dataset = _registry.datasets.register
44
+ register_loss = _registry.losses.register
45
+ register_optim = _registry.optims.register
46
+ register_sched = _registry.scheds.register
47
+ register_metric = _registry.metrics.register
48
+
49
+
50
+ # Ref constructors (v1.8+) — agent 가 직렬화 가능한 atom 참조 생성
51
+ def model_ref(name: str, params: dict | None = None) -> AtomRef:
52
+ """model AtomRef 생성. registry 의 model atom 을 직렬화 가능한 형태로 참조."""
53
+ return AtomRef(kind="model", name=name, params=dict(params or {}))
54
+
55
+
56
+ def dataset_ref(name: str, params: dict | None = None) -> AtomRef:
57
+ """dataset AtomRef 생성."""
58
+ return AtomRef(kind="dataset", name=name, params=dict(params or {}))
59
+
60
+
61
+ def loss_ref(name: str, params: dict | None = None) -> AtomRef:
62
+ """loss AtomRef 생성."""
63
+ return AtomRef(kind="loss", name=name, params=dict(params or {}))
64
+
65
+
66
+ def optim_ref(name: str, params: dict | None = None) -> AtomRef:
67
+ """optimizer AtomRef 생성. params 에는 lr 등 hyperparam 만 (model.parameters() 제외)."""
68
+ return AtomRef(kind="optim", name=name, params=dict(params or {}))
69
+
70
+
71
+ def sched_ref(name: str, params: dict | None = None) -> AtomRef:
72
+ """scheduler AtomRef 생성. params 에는 T_max 등만 (optimizer 제외)."""
73
+ return AtomRef(kind="sched", name=name, params=dict(params or {}))
74
+
75
+
76
+ def metric_ref(name: str, params: dict | None = None) -> AtomRef:
77
+ """metric AtomRef 생성."""
78
+ return AtomRef(kind="metric", name=name, params=dict(params or {}))
79
+
80
+
81
+ __version__ = "3.0.0"
82
+ __all__ = [
83
+ "AtomRef",
84
+ "AtomSpec",
85
+ "Experiment",
86
+ "ParamSpec",
87
+ "ResolvedConfig",
88
+ "RunContext",
89
+ "Trainer",
90
+ "agent",
91
+ "compare_runs",
92
+ "config",
93
+ "dataset_ref",
94
+ "datasets",
95
+ "describe_run",
96
+ "diff_recipes",
97
+ "examples",
98
+ "finalize_run",
99
+ "input_dir",
100
+ "inspect_project",
101
+ "list_meta",
102
+ "log",
103
+ "loss",
104
+ "loss_ref",
105
+ "metric",
106
+ "metric_ref",
107
+ "model_ref",
108
+ "models",
109
+ "optim",
110
+ "optim_ref",
111
+ "output_dir",
112
+ "recipe_meta",
113
+ "register_dataset",
114
+ "register_loss",
115
+ "register_metric",
116
+ "register_model",
117
+ "register_optim",
118
+ "register_sched",
119
+ "resolve_project",
120
+ "resolve_run_context",
121
+ "save_all",
122
+ "save_config_snapshot",
123
+ "save_manifest",
124
+ "save_metrics",
125
+ "save_partial_run_record",
126
+ "save_run_summary",
127
+ "sched",
128
+ "sched_ref",
129
+ "seed_everything",
130
+ "summarize_run",
131
+ "testing",
132
+ "validate_project",
133
+ ]
pcq/_registry.py ADDED
@@ -0,0 +1,17 @@
1
+ """Backward compat shim — actual implementation moved to pcq.registry package.
2
+
3
+ 기존 `from pcq import _registry` 또는 `from pcq._registry import models` 패턴을
4
+ 유지하기 위한 thin re-export. 신규 코드는 `from pcq.registry import ...` 사용.
5
+ """
6
+ from pcq.registry import ( # noqa: F401
7
+ AtomRef,
8
+ AtomSpec,
9
+ ParamSpec,
10
+ Registry,
11
+ datasets,
12
+ losses,
13
+ metrics,
14
+ models,
15
+ optims,
16
+ scheds,
17
+ )
pcq/agent/__init__.py ADDED
@@ -0,0 +1,264 @@
1
+ """pcq.agent — agent metadata + inspection + validation + summary.
2
+
3
+ v1.7 (Phase B): inspect / validate / summary 추가. 기존 v1.4 API
4
+ (recipe_meta, diff_recipes, list_meta) 는 그대로 유지.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ from typing import Any
9
+
10
+ from torch import nn
11
+
12
+ from pcq.agent.apply import (
13
+ ApplyResult,
14
+ PlanSetApplyResult,
15
+ apply_plan,
16
+ apply_planset,
17
+ )
18
+ from pcq.agent.compare import RunDiff, compare_runs
19
+ from pcq.agent.describe import RunDescription, describe_run
20
+ from pcq.agent.failure_classifier import classify_failure, enrich_failure
21
+ from pcq.agent.init import InitResult, init_experiment
22
+ from pcq.agent.install import (
23
+ AgentAssetStatus,
24
+ AgentInstallOperation,
25
+ AgentInstallResult,
26
+ AgentStatusResult,
27
+ agent_assets_status,
28
+ install_agent_assets,
29
+ )
30
+ from pcq.agent.json_contracts import (
31
+ JSON_CONTRACT_VERSION,
32
+ JSON_CONTRACTS,
33
+ get_json_contracts,
34
+ validate_json_contract,
35
+ )
36
+ from pcq.agent.inspect import inspect_project
37
+ from pcq.agent.lineage import (
38
+ LineageChain,
39
+ LineageNode,
40
+ is_descendant_of,
41
+ lineage,
42
+ )
43
+ from pcq.agent.plan import (
44
+ ChangeOp,
45
+ ExperimentPlan,
46
+ ExperimentPlanSet,
47
+ ValidationPolicy,
48
+ )
49
+ from pcq.agent.resolver import (
50
+ ResolvedConfig,
51
+ RunContext,
52
+ resolve_project,
53
+ resolve_run_context,
54
+ )
55
+ from pcq.agent.run_record import (
56
+ ERROR_CODES,
57
+ AgentInfo,
58
+ EnvironmentInfo,
59
+ ExecutionInfo,
60
+ FailureInfo,
61
+ MetricsInfo,
62
+ RunInfo,
63
+ RunRecord,
64
+ SourceInfo,
65
+ ValidationInfo,
66
+ category_to_error_code,
67
+ )
68
+ from pcq.agent.scaffold import ScaffoldResult, scaffold_atom, validate_local_atoms
69
+ from pcq.agent.schema import (
70
+ SCHEMA_VERSION,
71
+ CqYamlSummary,
72
+ EntrypointInfo,
73
+ EpochSummary,
74
+ OutputsInfo,
75
+ ProjectInspection,
76
+ RecipeInfo,
77
+ RecipeSpec,
78
+ RunSummary,
79
+ ValidationCheck,
80
+ ValidationReport,
81
+ )
82
+ from pcq.agent.smoke import SmokeReport, smoke_atom
83
+ from pcq.agent.strictness import (
84
+ STRICTNESS_EVIDENCE_MATRIX,
85
+ strictness_evidence_matrix,
86
+ strictness_required_evidence,
87
+ )
88
+ from pcq.agent.summary import build_run_summary, summarize_run
89
+ from pcq.agent.validate import validate_project
90
+ from pcq.agent.validate_run import validate_run
91
+
92
+
93
+ # recipe dict 의 metadata-only 키 (atom 이 아님)
94
+ _META_KEYS = {
95
+ "task",
96
+ "metrics",
97
+ "requires_extras",
98
+ "smoke_safe",
99
+ "smoke_overrides",
100
+ "epochs",
101
+ "batch_size",
102
+ }
103
+
104
+
105
+ def _atom_summary(value: Any) -> str:
106
+ """atom (model/dataset/loss/lambda) 을 사람·agent 가 읽을 수 있게 요약.
107
+
108
+ nn.Module → "ClassName (instance)"
109
+ callable → "callable<name>"
110
+ 그 외 → 타입 이름
111
+ """
112
+ if isinstance(value, nn.Module):
113
+ return f"{type(value).__name__} (instance)"
114
+ if callable(value):
115
+ name = getattr(value, "__name__", "<lambda>")
116
+ return f"callable<{name}>"
117
+ return type(value).__name__
118
+
119
+
120
+ def recipe_meta(preset: str) -> dict:
121
+ """Recipe metadata 추출. 학습 안 함, side effect 없음.
122
+
123
+ v1.4 API 유지. recipe 호출 실패(예: torchvision 미설치) 시 import_error
124
+ 필드만 채워진 degraded dict 반환.
125
+ """
126
+ from pcq.trainer import _import_recipe
127
+
128
+ fn = _import_recipe(preset)
129
+ try:
130
+ d = fn()
131
+ except Exception as e:
132
+ return {
133
+ "name": preset,
134
+ "task": None,
135
+ "declared_metrics": [],
136
+ "requires_extras": [],
137
+ "smoke_safe": None,
138
+ "has_smoke_overrides": False,
139
+ "atoms": {},
140
+ "epochs": None,
141
+ "batch_size": None,
142
+ "import_error": f"{type(e).__name__}: {e}",
143
+ }
144
+
145
+ atom_keys = (
146
+ "model",
147
+ "dataset_train",
148
+ "dataset_eval",
149
+ "dataset",
150
+ "loss",
151
+ "optim_factory",
152
+ "sched_factory",
153
+ )
154
+ atoms: dict[str, str] = {}
155
+ for key in atom_keys:
156
+ if key in d:
157
+ atoms[key] = _atom_summary(d[key])
158
+
159
+ return {
160
+ "name": preset,
161
+ "task": d.get("task", "classification"),
162
+ "declared_metrics": list(d.get("metrics", [])),
163
+ "requires_extras": list(d.get("requires_extras", [])),
164
+ "smoke_safe": d.get("smoke_safe"),
165
+ "has_smoke_overrides": bool(d.get("smoke_overrides")),
166
+ "atoms": atoms,
167
+ "epochs": d.get("epochs"),
168
+ "batch_size": d.get("batch_size"),
169
+ }
170
+
171
+
172
+ def diff_recipes(a: str, b: str) -> dict:
173
+ """두 recipe 의 atom + 설정 diff. agent 가 두 baseline 비교 시."""
174
+ ma, mb = recipe_meta(a), recipe_meta(b)
175
+ diff: dict[str, dict] = {}
176
+ for key in set(ma.keys()) | set(mb.keys()):
177
+ va, vb = ma.get(key), mb.get(key)
178
+ if va != vb:
179
+ diff[key] = {"a": va, "b": vb}
180
+ return {"a": a, "b": b, "diff": diff}
181
+
182
+
183
+ def list_meta() -> list[dict]:
184
+ """모든 등록된 recipe 의 metadata. agent 가 catalog 를 둘러볼 때."""
185
+ from pcq.trainer import Trainer
186
+
187
+ return [recipe_meta(p) for p in Trainer.list_presets()]
188
+
189
+
190
+ __all__ = [
191
+ "SCHEMA_VERSION",
192
+ "AgentInfo",
193
+ "AgentAssetStatus",
194
+ "AgentInstallOperation",
195
+ "AgentInstallResult",
196
+ "AgentStatusResult",
197
+ "ApplyResult",
198
+ "ChangeOp",
199
+ "CqYamlSummary",
200
+ "EntrypointInfo",
201
+ "EnvironmentInfo",
202
+ "EpochSummary",
203
+ "ERROR_CODES",
204
+ "ExecutionInfo",
205
+ "ExperimentPlan",
206
+ "ExperimentPlanSet",
207
+ "FailureInfo",
208
+ "InitResult",
209
+ "JSON_CONTRACT_VERSION",
210
+ "JSON_CONTRACTS",
211
+ "LineageChain",
212
+ "LineageNode",
213
+ "MetricsInfo",
214
+ "OutputsInfo",
215
+ "PlanSetApplyResult",
216
+ "ProjectInspection",
217
+ "RecipeInfo",
218
+ "RecipeSpec",
219
+ "ResolvedConfig",
220
+ "RunContext",
221
+ "RunDescription",
222
+ "RunDiff",
223
+ "RunInfo",
224
+ "RunRecord",
225
+ "RunSummary",
226
+ "ScaffoldResult",
227
+ "SmokeReport",
228
+ "SourceInfo",
229
+ "STRICTNESS_EVIDENCE_MATRIX",
230
+ "ValidationCheck",
231
+ "ValidationInfo",
232
+ "ValidationPolicy",
233
+ "ValidationReport",
234
+ "_atom_summary",
235
+ "apply_plan",
236
+ "apply_planset",
237
+ "build_run_summary",
238
+ "category_to_error_code",
239
+ "classify_failure",
240
+ "compare_runs",
241
+ "describe_run",
242
+ "diff_recipes",
243
+ "enrich_failure",
244
+ "get_json_contracts",
245
+ "init_experiment",
246
+ "agent_assets_status",
247
+ "install_agent_assets",
248
+ "inspect_project",
249
+ "is_descendant_of",
250
+ "lineage",
251
+ "list_meta",
252
+ "recipe_meta",
253
+ "resolve_project",
254
+ "resolve_run_context",
255
+ "scaffold_atom",
256
+ "smoke_atom",
257
+ "strictness_evidence_matrix",
258
+ "strictness_required_evidence",
259
+ "summarize_run",
260
+ "validate_local_atoms",
261
+ "validate_json_contract",
262
+ "validate_project",
263
+ "validate_run",
264
+ ]