aishipbox 0.1.0__tar.gz
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.
- aishipbox-0.1.0/.gitignore +25 -0
- aishipbox-0.1.0/.python-version +1 -0
- aishipbox-0.1.0/CLAUDE.md +67 -0
- aishipbox-0.1.0/OP_USAGE.md +361 -0
- aishipbox-0.1.0/PKG-INFO +171 -0
- aishipbox-0.1.0/README.md +159 -0
- aishipbox-0.1.0/aishipbox/__init__.py +3 -0
- aishipbox-0.1.0/aishipbox/__main__.py +6 -0
- aishipbox-0.1.0/aishipbox/algo/__init__.py +58 -0
- aishipbox-0.1.0/aishipbox/algo/commands/__init__.py +0 -0
- aishipbox-0.1.0/aishipbox/algo/commands/debug.py +40 -0
- aishipbox-0.1.0/aishipbox/algo/commands/install_deps.py +47 -0
- aishipbox-0.1.0/aishipbox/algo/commands/new.py +96 -0
- aishipbox-0.1.0/aishipbox/algo/commands/pack.py +32 -0
- aishipbox-0.1.0/aishipbox/algo/commands/run.py +42 -0
- aishipbox-0.1.0/aishipbox/algo/commands/stubs.py +31 -0
- aishipbox-0.1.0/aishipbox/algo/runner.py +126 -0
- aishipbox-0.1.0/aishipbox/algo/stubs/__init__.py +1 -0
- aishipbox-0.1.0/aishipbox/algo/stubs/pyproject.toml +12 -0
- aishipbox-0.1.0/aishipbox/algo/stubs/rest/__init__.py +1 -0
- aishipbox-0.1.0/aishipbox/algo/stubs/rest/process_base.py +6 -0
- aishipbox-0.1.0/aishipbox/algo/templates/AGENTS.md.tmpl +22 -0
- aishipbox-0.1.0/aishipbox/algo/templates/__init__.py +1 -0
- aishipbox-0.1.0/aishipbox/algo/templates/basic/.env.example +5 -0
- aishipbox-0.1.0/aishipbox/algo/templates/basic/__init__.py +1 -0
- aishipbox-0.1.0/aishipbox/algo/templates/basic/main.py +27 -0
- aishipbox-0.1.0/aishipbox/algo/templates/basic/requirements.txt +13 -0
- aishipbox-0.1.0/aishipbox/algo/templates/basic/utils.py +6 -0
- aishipbox-0.1.0/aishipbox/algo/templates/cv/.env.example +5 -0
- aishipbox-0.1.0/aishipbox/algo/templates/cv/__init__.py +1 -0
- aishipbox-0.1.0/aishipbox/algo/templates/cv/main.py +86 -0
- aishipbox-0.1.0/aishipbox/algo/templates/cv/requirements.txt +13 -0
- aishipbox-0.1.0/aishipbox/algo/templates/cv/utils.py +23 -0
- aishipbox-0.1.0/aishipbox/algo/templates/predict/.env.example +5 -0
- aishipbox-0.1.0/aishipbox/algo/templates/predict/__init__.py +1 -0
- aishipbox-0.1.0/aishipbox/algo/templates/predict/main.py +88 -0
- aishipbox-0.1.0/aishipbox/algo/templates/predict/requirements.txt +13 -0
- aishipbox-0.1.0/aishipbox/algo/templates/predict/utils.py +13 -0
- aishipbox-0.1.0/aishipbox/cli.py +52 -0
- aishipbox-0.1.0/aishipbox/core/__init__.py +0 -0
- aishipbox-0.1.0/aishipbox/core/config.py +84 -0
- aishipbox-0.1.0/aishipbox/core/env.py +25 -0
- aishipbox-0.1.0/aishipbox/core/packaging.py +52 -0
- aishipbox-0.1.0/aishipbox/core/strings.py +47 -0
- aishipbox-0.1.0/aishipbox/core/ui.py +69 -0
- aishipbox-0.1.0/aishipbox/core/venv.py +61 -0
- aishipbox-0.1.0/aishipbox/op/__init__.py +117 -0
- aishipbox-0.1.0/aishipbox/op/commands/__init__.py +0 -0
- aishipbox-0.1.0/aishipbox/op/commands/debug.py +28 -0
- aishipbox-0.1.0/aishipbox/op/commands/dep.py +141 -0
- aishipbox-0.1.0/aishipbox/op/commands/new.py +143 -0
- aishipbox-0.1.0/aishipbox/op/commands/pack.py +61 -0
- aishipbox-0.1.0/aishipbox/op/commands/run.py +86 -0
- aishipbox-0.1.0/aishipbox/op/ma_utils_mock/__init__.py +0 -0
- aishipbox-0.1.0/aishipbox/op/ma_utils_mock/ma_utils/__init__.py +27 -0
- aishipbox-0.1.0/aishipbox/op/manifest.py +284 -0
- aishipbox-0.1.0/aishipbox/op/moxing_mock/__init__.py +0 -0
- aishipbox-0.1.0/aishipbox/op/moxing_mock/moxing/__init__.py +1 -0
- aishipbox-0.1.0/aishipbox/op/moxing_mock/moxing/file.py +171 -0
- aishipbox-0.1.0/aishipbox/op/runner.py +231 -0
- aishipbox-0.1.0/aishipbox/op/templates/AGENTS.md.tmpl +281 -0
- aishipbox-0.1.0/aishipbox/op/templates/__init__.py +0 -0
- aishipbox-0.1.0/aishipbox/op/templates/env.example.tmpl +6 -0
- aishipbox-0.1.0/aishipbox/op/templates/gitignore.tmpl +8 -0
- aishipbox-0.1.0/aishipbox/op/templates/install.sh.example.tmpl +14 -0
- aishipbox-0.1.0/aishipbox/op/templates/process.blank.py.tmpl +47 -0
- aishipbox-0.1.0/aishipbox/op/templates/process.transform.py.tmpl +64 -0
- aishipbox-0.1.0/aishipbox/op/templates/requirements.txt.tmpl +16 -0
- aishipbox-0.1.0/aishipbox/op/wizard.py +32 -0
- aishipbox-0.1.0/docs/superpowers/plans/2026-05-11-aishipbox.md +3406 -0
- aishipbox-0.1.0/docs/superpowers/specs/2026-05-11-aishipbox-design.md +310 -0
- aishipbox-0.1.0/pyproject.toml +32 -0
- aishipbox-0.1.0/tests/__init__.py +0 -0
- aishipbox-0.1.0/tests/algo/__init__.py +0 -0
- aishipbox-0.1.0/tests/algo/test_debug.py +13 -0
- aishipbox-0.1.0/tests/algo/test_dispatch.py +19 -0
- aishipbox-0.1.0/tests/algo/test_new.py +56 -0
- aishipbox-0.1.0/tests/algo/test_pack.py +29 -0
- aishipbox-0.1.0/tests/algo/test_run.py +31 -0
- aishipbox-0.1.0/tests/conftest.py +9 -0
- aishipbox-0.1.0/tests/core/__init__.py +0 -0
- aishipbox-0.1.0/tests/core/test_config.py +39 -0
- aishipbox-0.1.0/tests/core/test_env.py +23 -0
- aishipbox-0.1.0/tests/core/test_packaging.py +48 -0
- aishipbox-0.1.0/tests/core/test_strings.py +27 -0
- aishipbox-0.1.0/tests/core/test_ui.py +44 -0
- aishipbox-0.1.0/tests/core/test_venv.py +41 -0
- aishipbox-0.1.0/tests/integration/__init__.py +0 -0
- aishipbox-0.1.0/tests/integration/conftest.py +35 -0
- aishipbox-0.1.0/tests/integration/test_algo_e2e.py +35 -0
- aishipbox-0.1.0/tests/integration/test_op_e2e.py +481 -0
- aishipbox-0.1.0/tests/op/__init__.py +0 -0
- aishipbox-0.1.0/tests/op/test_debug.py +10 -0
- aishipbox-0.1.0/tests/op/test_dep.py +214 -0
- aishipbox-0.1.0/tests/op/test_dispatch.py +75 -0
- aishipbox-0.1.0/tests/op/test_ma_utils_mock.py +36 -0
- aishipbox-0.1.0/tests/op/test_manifest.py +310 -0
- aishipbox-0.1.0/tests/op/test_moxing_mock.py +197 -0
- aishipbox-0.1.0/tests/op/test_new.py +140 -0
- aishipbox-0.1.0/tests/op/test_pack.py +68 -0
- aishipbox-0.1.0/tests/op/test_run.py +111 -0
- aishipbox-0.1.0/tests/test_cli.py +44 -0
- aishipbox-0.1.0/uv.lock +310 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Python-generated files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[oc]
|
|
4
|
+
build/
|
|
5
|
+
dist/
|
|
6
|
+
wheels/
|
|
7
|
+
*.egg-info
|
|
8
|
+
.pytest_cache/
|
|
9
|
+
.coverage
|
|
10
|
+
|
|
11
|
+
# Virtual environments
|
|
12
|
+
.venv
|
|
13
|
+
|
|
14
|
+
# Env files
|
|
15
|
+
.env
|
|
16
|
+
|
|
17
|
+
# Build artifacts
|
|
18
|
+
*.tar
|
|
19
|
+
*.tar.gz
|
|
20
|
+
|
|
21
|
+
# Reference material (not part of the package)
|
|
22
|
+
resources/
|
|
23
|
+
|
|
24
|
+
# macOS
|
|
25
|
+
.DS_Store
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Commands
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
uv sync # install deps (runtime + dev)
|
|
9
|
+
uv run pytest # unit tests (fast, no venv provisioning)
|
|
10
|
+
uv run pytest -m integration # end-to-end; needs uv able to provide Python 3.9/3.10
|
|
11
|
+
uv run pytest tests/op/test_manifest.py::test_render_minimal -v # one test
|
|
12
|
+
uv run aishipbox --help # smoke the CLI
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Integration tests call `uv venv --python <ver>`. In offline environments, set `UV_PYTHON_DOWNLOADS=never` and they'll skip cleanly rather than hang trying to fetch interpreters.
|
|
16
|
+
|
|
17
|
+
## Architecture
|
|
18
|
+
|
|
19
|
+
Three top-level subpackages with strict dependency direction:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
aishipbox/cli.py # thin dispatch only — never grows logic
|
|
23
|
+
│
|
|
24
|
+
├── core/ # infrastructure: config, env, venv, packaging, ui, strings
|
|
25
|
+
│ knows nothing about algo or op
|
|
26
|
+
├── algo/ # MAS algorithm services (absorbed from mas-algo-cli)
|
|
27
|
+
│ Python 3.9 hosted runtime
|
|
28
|
+
└── op/ # PanguLM custom operators (built fresh)
|
|
29
|
+
Python 3.10 hosted runtime
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`algo/` and `op/` are **siblings, never import from each other**. Anything they'd both use belongs in `core/`.
|
|
33
|
+
|
|
34
|
+
## Invariants
|
|
35
|
+
|
|
36
|
+
- **Per-project venv.** `algo run` / `op run` always exec the project's `.venv/bin/python`, never `sys.executable`. Hosted Python versions live in `HOSTED_RUNTIMES` (core/config.py) — bump there when the platform changes; existing projects keep their pinned version via `.aishipbox.toml`.
|
|
37
|
+
- **`.aishipbox.toml` is the project marker.** Its `type` field routes in-project commands. Don't read project type from filenames.
|
|
38
|
+
- **All user-facing strings live in `core/strings.py`** (Chinese). Don't hardcode strings in commands — add a constant. The codebase grep-tests for English leaks.
|
|
39
|
+
- **`uv` is required at runtime**, not a fallback. `core.venv.require_uv()` raises `UvNotFound` instead of falling back to `python -m venv`.
|
|
40
|
+
- **moxing_mock is shadow-imported via PYTHONPATH** only during `op run` mock mode. Don't add it to the project's `requirements.txt`.
|
|
41
|
+
|
|
42
|
+
## Generated project layout
|
|
43
|
+
|
|
44
|
+
Each `aishipbox <type> new` writes a `.aishipbox.toml` (project marker) and `AGENTS.md` (agent guidance for that specific project, in Chinese). Per-project structure:
|
|
45
|
+
|
|
46
|
+
- **algo:** `main.py`, `requirements.txt`, `dependency/`, `lib/`, `.venv/` (3.9)
|
|
47
|
+
- **op:** `manifest.yml`, `program_package/{process.py,requirements.txt}`, `obs_input/`, `obs_output/` (mock), `.venv/` (3.10)
|
|
48
|
+
|
|
49
|
+
## Pack output format
|
|
50
|
+
|
|
51
|
+
- algo → `<name>.tar.gz` at the service dir (flat, no top-level folder).
|
|
52
|
+
- op → `program_package/<id>.tar` (uncompressed). Per the PanguLM spec the archive nests under the operator id: `<id>/manifest.yml` sits beside `<id>/program_package/{process.py,dependency/,...}`. `*.tar` and `*.example` siblings are excluded from the pack.
|
|
53
|
+
|
|
54
|
+
## Documentation
|
|
55
|
+
|
|
56
|
+
- Design: `docs/superpowers/specs/2026-05-11-aishipbox-design.md` — decisions and rationale
|
|
57
|
+
- Implementation plan: `docs/superpowers/plans/2026-05-11-aishipbox.md` — task-by-task TDD plan
|
|
58
|
+
- Reference operator: `resources/labelme2pascal_voc-workground/` (gitignored, kept locally)
|
|
59
|
+
- Reference for the absorb: `resources/mas-algo-cli/` (gitignored)
|
|
60
|
+
|
|
61
|
+
## What not to do
|
|
62
|
+
|
|
63
|
+
- Don't `import sys.executable` for project subprocess invocations.
|
|
64
|
+
- Don't add user-facing English strings; route through `core/strings.py`.
|
|
65
|
+
- Don't import from `aishipbox.algo` in `aishipbox.op` (or vice versa).
|
|
66
|
+
- Don't commit `resources/`; it's reference material, gitignored.
|
|
67
|
+
- Don't add `mas-algo-cli` as a runtime dep — it was absorbed.
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
# 自定义算子(op)使用指南
|
|
2
|
+
|
|
3
|
+
本指南从概念到工具到 agent 协作,分四部分:
|
|
4
|
+
|
|
5
|
+
- [1. 什么是自定义算子](#1-什么是自定义算子)
|
|
6
|
+
- [2. 怎么构建自定义算子(接口定义)](#2-怎么构建自定义算子接口定义)
|
|
7
|
+
- [3. 使用 aishipbox 构建算子](#3-使用-aishipbox-构建算子)
|
|
8
|
+
- [4. 用 coding agent 配合 aishipbox 快速构建](#4-用-coding-agent-配合-aishipbox-快速构建)
|
|
9
|
+
- [端到端示例](#端到端示例)
|
|
10
|
+
- [FAQ](#faq)
|
|
11
|
+
- [参考](#参考)
|
|
12
|
+
|
|
13
|
+
> 前置:先装好 uv(见 [uv 官方安装文档](https://docs.astral.sh/uv/getting-started/installation/)),然后 `uv tool install aishipbox`。托管运行时为 **Python 3.10**。
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 1. 什么是自定义算子
|
|
18
|
+
|
|
19
|
+
自定义算子(custom operator)是 ModelArts Studio **数据集加工**里的一个处理节点。平台把数据集按你声明的方式喂给算子,算子做一段处理(提取、抽样、转换、过滤、去重、打标……),产出加工后的数据。
|
|
20
|
+
|
|
21
|
+
一条数据集加工流水线由**多个算子串联**而成:平台编排这些节点,上一个算子写到 OBS 的输出就是下一个算子的输入。
|
|
22
|
+
|
|
23
|
+
```mermaid
|
|
24
|
+
flowchart LR
|
|
25
|
+
DS["数据集<br/>(OBS)"] --> OP1["自定义算子 1<br/>如:过滤"]
|
|
26
|
+
OP1 -->|"OBS 输出 → 输入"| OP2["自定义算子 2<br/>如:转换"]
|
|
27
|
+
OP2 -->|"OBS 输出 → 输入"| OP3["自定义算子 3<br/>如:打标"]
|
|
28
|
+
OP3 --> OUT["加工后数据集<br/>(OBS)"]
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
> - 单个算子无法编排别的算子,"串联多个算子"是**平台流水线**的职责。本指南聚焦如何构建流水线里的**一个**自定义算子节点。
|
|
32
|
+
> - **目前平台不支持内置算子与自定义算子混用**:同一条流水线要么全用内置算子,要么全用自定义算子。
|
|
33
|
+
|
|
34
|
+
放大看其中一个节点:平台运行一个算子的大致生命周期:
|
|
35
|
+
|
|
36
|
+
```mermaid
|
|
37
|
+
flowchart TD
|
|
38
|
+
A["拉起托管容器(基于MA)<br/>Python 3.10 · ARM/X86<br/>基础镜像内置250 个预置包"] --> B["装额外依赖<br/>pip install --no-index<br/>--find-links=./dependency"]
|
|
39
|
+
B --> C["实例化算子链<br/>PreProcess / Process / PostProcess<br/>__init__ 整次运行只调一次"]
|
|
40
|
+
C --> D{"auto-data-loading?"}
|
|
41
|
+
D -->|"true(模式一)"| E["框架读 OBS 输入<br/>按文件类型构造 DataFrame<br/>逐文件喂入"]
|
|
42
|
+
E --> F["对每个文件依次调用<br/>PreProcess → Process → PostProcess"]
|
|
43
|
+
F --> G["收集 __call__ 返回的 DataFrame<br/>框架写回 OBS 输出"]
|
|
44
|
+
D -->|"false(模式二)"| H["框架传入空 DataFrame<br/>算子自行从 args.obs_input_path<br/>用 moxing 读 OBS"]
|
|
45
|
+
H --> I["整条算子链只调用一次<br/>PreProcess → Process → PostProcess(无逐文件循环)"]
|
|
46
|
+
I --> J["算子自行用 moxing<br/>写 args.obs_output_path"]
|
|
47
|
+
G --> K["输出落到 OBS<br/>进入下一个加工节点"]
|
|
48
|
+
J --> K
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
一个算子要回答三个问题:
|
|
52
|
+
|
|
53
|
+
- **它是什么** —— 元数据:ID、名称、版本、处理类别、数据模态、资源需求、可调参数。这些写在 `manifest.yml`。
|
|
54
|
+
- **它怎么处理数据** —— 实现:`process.py` 里的 `Process` 类。平台按接口协议调用它。
|
|
55
|
+
- **它怎么部署** —— 打包:按平台规范打成一个 `.tar`,上传到平台。
|
|
56
|
+
|
|
57
|
+
算子运行在平台托管的 Linux 容器里(**Python 3.10**,ARM 或 X86),通过 `moxing`(OBS 对象存储访问)和 `ma_utils`(日志)等平台 SDK 与基础设施交互。基础镜像预装约 250 个常用包(pandas/numpy/torch/transformers/pyarrow/opencv-python/pillow/moxing-framework 等)。
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## 2. 怎么构建自定义算子(接口定义)
|
|
62
|
+
|
|
63
|
+
这一节讲**算子接口定义**。第 3 节再讲引入一个工具 aishipbox,把这些内容自动化。
|
|
64
|
+
|
|
65
|
+
### 2.1 manifest.yml —— 算子是什么
|
|
66
|
+
|
|
67
|
+
声明元数据与可调参数。关键字段:
|
|
68
|
+
|
|
69
|
+
- 顶层:`id`(英文字母开头、`[A-Za-z0-9_]`、≤128、创建后不可变)、`name`、`version`(`x.y.z`)、`description`、`author`。
|
|
70
|
+
- `tags`:`category`(单选:数据提取/抽样/转换/过滤/去重/打标/其他)、`modal`(TEXT/IMAGE/VIDEO/AUDIO/OTHER)、`format`(**必填,不能为空**,如 JSONL/CSV/MP4)、`language`。
|
|
71
|
+
- `runtime`:`cpu-arch`(ARM / X86)、`resources`(cpu/memory/npu)、`environment: python`、`entrypoint: process.py`、`auto-data-loading`(见 2.3)。
|
|
72
|
+
- `arguments`:业务参数(STRING/FLOAT/INT/ENUM/LIST/OBS/BOOLEAN…),运行时挂到 `args.<key>`。
|
|
73
|
+
- `labels`:打标类算子的输出标签定义。
|
|
74
|
+
|
|
75
|
+
> 完整字段规范(类型、必填/可选、枚举、示例)见每个 aishipbox 项目自带的 `AGENTS.md`。
|
|
76
|
+
|
|
77
|
+
### 2.2 process.py —— 算子怎么处理数据
|
|
78
|
+
|
|
79
|
+
入口是 `Process` 类(必填,实现 `__call__`)。平台按 **PreProcess → Process → PostProcess** 顺序调用,前后两个可选:
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
class PreProcess: # 可选;CPU 侧轻量预处理,提升 NPU 利用率
|
|
83
|
+
def __init__(self, args): ...
|
|
84
|
+
def __call__(self, input): ...
|
|
85
|
+
|
|
86
|
+
class Process: # 必填;模型加载与推理主逻辑
|
|
87
|
+
def __init__(self, args): ...
|
|
88
|
+
def __call__(self, input): ...
|
|
89
|
+
|
|
90
|
+
class PostProcess: # 可选;推理后 CPU 侧处理
|
|
91
|
+
def __init__(self, args): ...
|
|
92
|
+
def __call__(self, input): ...
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
- `__init__` 整次运行**只调一次**(适合加载模型 / 分配状态)。
|
|
96
|
+
- `args` 是框架注入的对象,含 `args.obs_input_path` / `args.obs_output_path`,以及 manifest 里声明的业务参数(`args.<key>`)。
|
|
97
|
+
- 日志用平台入口,**不要**用 `logging.basicConfig`:
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
import ma_utils as utils
|
|
101
|
+
logger = utils.FileLogger.get_logger()
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### 2.3 两种运行模式(auto-data-loading)
|
|
105
|
+
|
|
106
|
+
由 `manifest.yml > runtime > auto-data-loading` 决定,是构建算子时最重要的一个选择:
|
|
107
|
+
|
|
108
|
+
| 模式 | 设置 | 输入 | 输出 | 适用 |
|
|
109
|
+
|---|---|---|---|---|
|
|
110
|
+
| **模式一** | `true` | 框架按文件类型构造 pandas.DataFrame,**逐文件**调用算子链 | `__call__` 返回 DataFrame,框架写回 | 单模态、按样本/按文件处理 |
|
|
111
|
+
| **模式二** | `false` | 空 DataFrame;自行从 `args.obs_input_path` 读 | 无返回值,自行写 `args.obs_output_path` | 多模态、跨样本(如去重)、非标准输出 |
|
|
112
|
+
|
|
113
|
+
**模式一 DataFrame 形状**(按输入文件扩展名分派):
|
|
114
|
+
|
|
115
|
+
| 扩展名 | DataFrame 列 |
|
|
116
|
+
|---|---|
|
|
117
|
+
| `.jsonl` / `.csv` | 文件自身字段 |
|
|
118
|
+
| `.parquet` | 文件自身字段 + 注入 `file_path` / `file_name` |
|
|
119
|
+
| 其他 | 单行 `file_path` + `file_name` |
|
|
120
|
+
|
|
121
|
+
模式一要求:`__call__` 每文件调一次、必须返回 DataFrame;同一输入目录**不能混合**上述类型。需要多模态/跨样本就用模式二。
|
|
122
|
+
|
|
123
|
+
### 2.4 OBS 访问(moxing.file)
|
|
124
|
+
|
|
125
|
+
无论哪种模式,文件 I/O 都走 `moxing`:
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
import moxing as mox
|
|
129
|
+
mox.file.copy("obs://input/a.jpg", "obs://output/a.jpg")
|
|
130
|
+
mox.file.list_directory("obs://input/", recursive=True)
|
|
131
|
+
data = mox.file.read("obs://input/a.txt")
|
|
132
|
+
mox.file.write("obs://output/b.txt", "...")
|
|
133
|
+
# 另有 copy_parallel / append / exists / glob / walk / stat / remove / rename / ...
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### 2.5 打包规范
|
|
137
|
+
|
|
138
|
+
平台要求算子包是一个 `.tar`,内部按算子 `id` 嵌套:
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
<id>/
|
|
142
|
+
├── manifest.yml
|
|
143
|
+
└── program_package/
|
|
144
|
+
├── process.py
|
|
145
|
+
├── dependency/requirements.txt # 平台没有的额外依赖
|
|
146
|
+
└── install.sh # 可选,自定义安装步骤
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
平台运行时执行 `pip install --no-index --find-links=./dependency -r ./dependency/requirements.txt` —— `--no-index` 意味着只能从 `dependency/` 找 wheel,所以预装包不要写进 `requirements.txt`,且额外依赖的 wheel 必须是 Linux + Python 3.10 + 对应架构。
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## 3. 使用 aishipbox 构建算子
|
|
154
|
+
|
|
155
|
+
aishipbox 把第 2 节的构建流程自动化。命令速查:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
aishipbox op new <name> [flags] # 新建项目(脚手架 + venv + 预置包)
|
|
159
|
+
aishipbox op run [path] # 本地运行(默认 mock 模式)
|
|
160
|
+
aishipbox op run --obs # 用真实 OBS 运行(读 .env)
|
|
161
|
+
aishipbox op run --debug # 启动后等 VS Code 在 5678 端口附加
|
|
162
|
+
aishipbox op debug [path] # 生成 .vscode/launch.json
|
|
163
|
+
aishipbox op download <pkg> [path] # 下载依赖 wheel 到 dependency/ 并写 requirements.txt
|
|
164
|
+
aishipbox op pack [path] # 打包成 program_package/<id>.tar
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
`path` 默认当前目录;命令多在算子项目根目录内执行。
|
|
168
|
+
|
|
169
|
+
### 3.1 op new —— 新建项目
|
|
170
|
+
|
|
171
|
+
**交互式(人工首次使用):**
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
aishipbox op new my_op
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
进入向导逐项填写 ID/名称/版本/类别/模态/架构/资源/模式/骨架。
|
|
178
|
+
|
|
179
|
+
**非交互式(脚本 / agent):** 带 `--yes` 即可,未提供的字段用默认值填充:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
aishipbox op new my_op --yes # 全默认
|
|
183
|
+
aishipbox op new my_op --yes \ # 或只覆盖关心的字段
|
|
184
|
+
--category 数据转换 --modal IMAGE --auto-data-loading=false --skeleton transform
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
字段默认值(与向导一致):`id`/`name`=项目名、`version`=`0.0.1`、`category`=`其他`、`modal`=`[OTHER]`、`format`=`[OTHER]`、`cpu-arch`=`[ARM]`、`cpu`=`1`、`memory`=`2048`、`npu`=`0`、`auto-data-loading`=`false`、`skeleton`=`transform`。可选值见项目内 `AGENTS.md`。
|
|
188
|
+
|
|
189
|
+
> 非交互环境(管道 / 无 TTY)下漏掉 `--yes` 不会卡在向导上 —— 会立即报错提示改用 `--yes`,退出码 `2`。
|
|
190
|
+
|
|
191
|
+
`--skeleton` 选 `blank`(空白)或 `transform`(含 moxing 文件拷贝示例,对应模式二)。
|
|
192
|
+
|
|
193
|
+
新建后的目录:
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
my_op/
|
|
197
|
+
├── manifest.yml # 算子元数据
|
|
198
|
+
├── program_package/
|
|
199
|
+
│ ├── process.py # 算子主实现(必填)
|
|
200
|
+
│ ├── dependency/requirements.txt # 平台预置之外的依赖
|
|
201
|
+
│ └── install.sh.example # 自定义安装步骤模板
|
|
202
|
+
├── obs_input/ obs_output/ # 本地 mock 输入/输出
|
|
203
|
+
├── .env.example # --obs 模式凭据模板
|
|
204
|
+
├── AGENTS.md .aishipbox.toml .gitignore
|
|
205
|
+
└── .venv/ # Python 3.10(已装好平台预置的 pandas/numpy/pyarrow)
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### 3.2 实现算子
|
|
209
|
+
|
|
210
|
+
编辑 `program_package/process.py`,按第 2.2 / 2.3 节的接口定义实现 `Process`(及可选的 Pre/PostProcess)。先 `cat manifest.yml` 确认当前是模式一还是模式二。
|
|
211
|
+
|
|
212
|
+
### 3.3 op run —— 本地运行与 mock
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
cd my_op
|
|
216
|
+
# 把测试数据放进 obs_input/
|
|
217
|
+
aishipbox op run # mock 模式(默认)
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
mock 模式把平台依赖在本地等价模拟:
|
|
221
|
+
|
|
222
|
+
- **`moxing.file`**:`obs://input/` → `obs_input/`,`obs://output/` → `obs_output/`;**其他 bucket 名会立即报错**(只在这两条路径上保证等价)。覆盖 18 个 API(list_directory / copy / copy_parallel / read / write / append / glob / walk / stat / exists / is_directory / make_dirs / mk_dir / remove / rename / get_size / scan_dir / File)。
|
|
223
|
+
- **`ma_utils.FileLogger.get_logger()`**:返回配置好格式的本地 logger。
|
|
224
|
+
- 模式一下,各文件返回的 DataFrame 会汇总写到 `obs_output/result.jsonl`(仅本地约定)。
|
|
225
|
+
|
|
226
|
+
**真实 OBS:**
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
cp .env.example .env # 填 OBS_AK/SK/ENDPOINT/INPUT_PATH/OUTPUT_PATH
|
|
230
|
+
aishipbox op run --obs
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### 3.4 op debug —— 断点调试
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
aishipbox op debug # 生成 .vscode/launch.json("Attach to Op Service")
|
|
237
|
+
aishipbox op run --debug # 启动后等 VS Code 在 5678 端口附加
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
在 VS Code 选 "Attach to Op Service" 即可命中 `process.py` 断点。
|
|
241
|
+
|
|
242
|
+
### 3.5 op download —— 添加依赖
|
|
243
|
+
|
|
244
|
+
只有平台**没有**的包才需要打进算子包。`op download` 自动处理跨平台 wheel:
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
aishipbox op download requests
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
它按 `manifest.yml > runtime > cpu-arch` 选目标平台(`ARM`→`manylinux2014_aarch64`,`X86`→`manylinux2014_x86_64`),下载 **Linux + Python 3.10** 的 wheel 到 `dependency/`(`--no-deps`,不拉传递依赖),并把 `<package>==<version>` 写入 `requirements.txt`。
|
|
251
|
+
|
|
252
|
+
- 与开发机平台无关(macOS/Windows 上也能下到正确的 Linux wheel)。
|
|
253
|
+
- 平台预置包会被拒绝下载(pandas/numpy/pyarrow,大小写不敏感)。
|
|
254
|
+
- 可重复执行(幂等),多架构会各下一份并校验版本一致。
|
|
255
|
+
- 无法从 PyPI 获取的依赖:手动放 `.whl` 进 `dependency/`,复杂步骤写进 `install.sh`(参考 `install.sh.example`)。
|
|
256
|
+
|
|
257
|
+
### 3.6 op pack —— 打包
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
aishipbox op pack # → program_package/<id>.tar
|
|
261
|
+
aishipbox op pack --force # 覆盖已存在的 tar
|
|
262
|
+
aishipbox op pack -o out.tar # 指定输出路径
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
打包前校验 `manifest.yml`(不合规直接报错列出全部问题)和 `process.py`(须含 `Process` 类)。产物是未压缩 `.tar`,按第 2.5 节规范嵌套于 `<id>/` 下;`obs_input/`、`obs_output/`、`AGENTS.md`、`.aishipbox.toml` 及 `*.tar`/`*.example` 不会被打进包。
|
|
266
|
+
|
|
267
|
+
**改动 `manifest.yml` 或依赖后必须重新 `pack`。**
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## 4. 用 coding agent 配合 aishipbox 快速构建
|
|
272
|
+
|
|
273
|
+
aishipbox 也考虑和 coding agent(Claude Code 等)协作设计:命令非交互友好(`--yes` 永不卡住),每个项目自带 `AGENTS.md` 作为 agent 的项目内操作手册(含完整 manifest 字段规范与约束)。
|
|
274
|
+
|
|
275
|
+
### 4.1 分工:人起项目,agent 实现
|
|
276
|
+
|
|
277
|
+
推荐流程是**人先用 `op new` 起好项目骨架**(确定算子身份:id/类别/模态/模式),**再让 agent 接手**填 manifest 细节、实现 process.py、本地验证、打包。
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
# 人:起项目(选好模式与骨架)
|
|
281
|
+
aishipbox op new img_dedup --yes \
|
|
282
|
+
--category 数据去重 --modal IMAGE --auto-data-loading=false --skeleton transform
|
|
283
|
+
cd img_dedup
|
|
284
|
+
# 在这个目录里启动你的 coding agent(它会读到项目内 AGENTS.md)
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
然后 agent 的典型步骤:
|
|
288
|
+
|
|
289
|
+
1. **读 `AGENTS.md`** —— 拿到 manifest 完整字段规范、两种模式契约、moxing/ma_utils 用法、约束。
|
|
290
|
+
2. **编辑 `manifest.yml`** —— 补 description/arguments/resources 等细节(直接改文件,比堆一长串 flag 可靠)。
|
|
291
|
+
3. **实现 `program_package/process.py`** —— 按当前模式写 Process 逻辑。
|
|
292
|
+
4. **加依赖**(按需):`aishipbox op download <pkg>`。
|
|
293
|
+
5. **本地验证**:把样例放进 `obs_input/`,跑 `aishipbox op run`,看 `obs_output/`。
|
|
294
|
+
6. **打包**:`aishipbox op pack`。
|
|
295
|
+
|
|
296
|
+
### 4.2 示例 prompt → agent 动作
|
|
297
|
+
|
|
298
|
+
把项目起好、在项目目录里启动 agent 后,可以这样让它干活:
|
|
299
|
+
|
|
300
|
+
**示例 A —— 实现一个图片去重算子(模式二):**
|
|
301
|
+
|
|
302
|
+
> 「读 AGENTS.md。这是个 IMAGE 模态、数据去重、auto-data-loading=false 的算子。请在 process.py 里实现:从 args.obs_input_path 读取所有图片,按内容 hash 去重,把保留的图片写到 args.obs_output_path。需要的依赖用 `aishipbox op download` 装。然后跑 `aishipbox op run` 验证,最后 `aishipbox op pack`。」
|
|
303
|
+
|
|
304
|
+
agent 会依次:读 AGENTS.md → 写 `Process.__call__`(用 `mox.file.list_directory` / `copy`)→ `aishipbox op download imagehash` → `aishipbox op run` → 看 `obs_output/` → `aishipbox op pack`。
|
|
305
|
+
|
|
306
|
+
**示例 B —— 在已有项目上加业务参数:**
|
|
307
|
+
|
|
308
|
+
> 「给这个算子加一个 FLOAT 参数 threshold(默认 0.9,范围 0~1),在 manifest.yml 的 arguments 里声明,并在 process.py 里用 args.threshold。改完重新 pack。」
|
|
309
|
+
|
|
310
|
+
agent 会:按 AGENTS.md 的 arguments 规范改 `manifest.yml` → 在 `process.py` 用 `self.args.threshold` → `aishipbox op pack`(pack 会顺带校验 manifest)。
|
|
311
|
+
|
|
312
|
+
### 4.3 给 agent 的要点
|
|
313
|
+
|
|
314
|
+
- **始终带 `--yes`** 跑 `op new`(agent 环境无 TTY,否则报错)。
|
|
315
|
+
- **manifest 细节直接编辑文件**,不必都用 flag。
|
|
316
|
+
- **`AGENTS.md` 是权威参考**,字段枚举/约束以它为准。
|
|
317
|
+
- **每改 manifest 或依赖就 `op pack`**,pack 自带校验,是最省事的「lint」。
|
|
318
|
+
- 本地 mock 只认 `obs://input/` 和 `obs://output/`,其他 OBS 路径需 `--obs` 模式。
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
## 端到端示例
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
# 1. 人:起项目(模式二 + transform 骨架)
|
|
326
|
+
aishipbox op new img_copy --yes \
|
|
327
|
+
--category 数据转换 --modal IMAGE --auto-data-loading=false --skeleton transform
|
|
328
|
+
cd img_copy
|
|
329
|
+
|
|
330
|
+
# 2. agent / 人:按需微调 manifest.yml(字段规范见 AGENTS.md)
|
|
331
|
+
|
|
332
|
+
# 3. 放测试数据
|
|
333
|
+
cp ~/some_images/*.jpg obs_input/
|
|
334
|
+
|
|
335
|
+
# 4. 实现 program_package/process.py 的 transform()
|
|
336
|
+
|
|
337
|
+
# 5. 加平台没有的依赖(按需)
|
|
338
|
+
aishipbox op download pillow
|
|
339
|
+
|
|
340
|
+
# 6. 本地跑,看 obs_output/
|
|
341
|
+
aishipbox op run
|
|
342
|
+
|
|
343
|
+
# 7. 打包上传
|
|
344
|
+
aishipbox op pack # → program_package/img_copy.tar
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## FAQ
|
|
350
|
+
|
|
351
|
+
- **向导卡住 / agent 无响应**:非交互环境忘了 `--yes`。补上即可(字段可省略走默认)。
|
|
352
|
+
- **`op run` 报缺少 pandas**:模式一需要 pandas,`op new` 已装平台预置版本进 `.venv/`。若 `.venv` 损坏,重跑 `op new`(换名或先删项目),或手动 `uv venv --python 3.10 .venv` 后装回预置包。预置包不能用 `op download`(会被拒绝)。
|
|
353
|
+
- **`其他 bucket 名报错`**:mock 只支持 `obs://input/` 和 `obs://output/`,其余路径用 `--obs` 连真实 OBS。
|
|
354
|
+
- **平台装包失败**:检查是否把预置包写进了 `requirements.txt`,或 wheel 架构/Python 版本不匹配(建议用 `op download` 自动下载)。
|
|
355
|
+
|
|
356
|
+
## 参考
|
|
357
|
+
|
|
358
|
+
- 平台手册:https://support.huaweicloud.com/usermanual-pangulm/pangulm_04_0043.html
|
|
359
|
+
- 算子配置文件规范:https://support.huaweicloud.com/usermanual-pangulm/pangulm_04_0044.html
|
|
360
|
+
- MoXing API:https://support.huaweicloud.com/usermanual-standard-modelarts/modelarts_11_0001.html
|
|
361
|
+
- 项目内 `AGENTS.md`:完整 manifest 字段规范 + 给 agent 的操作约束
|
aishipbox-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aishipbox
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: ModelArts Studio 自定义数据加工算子开发 CLI
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Requires-Dist: debugpy>=1.8.0
|
|
8
|
+
Requires-Dist: pyyaml>=6.0
|
|
9
|
+
Requires-Dist: questionary>=2.0.0
|
|
10
|
+
Requires-Dist: tomli>=2.0.0; python_version < '3.11'
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
|
|
13
|
+
# aishipbox
|
|
14
|
+
|
|
15
|
+
ModelArts Studio 算法包服务(algo)与自定义算子(op)开发 CLI。
|
|
16
|
+
|
|
17
|
+
把平台上线前后的本地等价开发环境收敛到一条命令链:脚手架、虚拟环境、本地 mock、调试、打包。
|
|
18
|
+
|
|
19
|
+
## 安装
|
|
20
|
+
|
|
21
|
+
需要先装 [uv](https://docs.astral.sh/uv/)(本工具的硬性依赖)—— 安装方法见 [uv 官方安装文档](https://docs.astral.sh/uv/getting-started/installation/)。
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
uv tool install aishipbox
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
更新已安装的工具:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
uv tool install --reinstall aishipbox # 从 PyPI
|
|
31
|
+
uv tool install --reinstall . # 从当前源码(dev)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## 使用指南
|
|
35
|
+
|
|
36
|
+
- 算子(op)完整开发流程:[OP_USAGE.md](OP_USAGE.md) —— 新建 → 实现 → 本地 mock 调试 → 加依赖 → 打包,含交互式与 agent 非交互式两条路径
|
|
37
|
+
|
|
38
|
+
## 设计
|
|
39
|
+
|
|
40
|
+
两个子命令完全隔离:项目结构、骨架模板、运行模型、打包格式独立演进。共用的基础设施(venv、env、字符串、packaging)放在 `core/`。
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
aishipbox/cli.py # 仅做分发
|
|
44
|
+
├── core/ # 共用基础设施
|
|
45
|
+
├── algo/ # 算法包服务(HTTP/gRPC 微服务),Python 3.9
|
|
46
|
+
└── op/ # 自定义数据加工算子(数据集流水线节点),Python 3.10
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`algo` 与 `op` **互不依赖**;公共逻辑都在 `core/`。
|
|
50
|
+
|
|
51
|
+
## 快速开始
|
|
52
|
+
|
|
53
|
+
### 算法服务(algo)
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
aishipbox algo new my_algo -t basic # basic / predict / cv
|
|
57
|
+
cd my_algo
|
|
58
|
+
aishipbox algo run # 本地起服务
|
|
59
|
+
aishipbox algo pack # 打 tar.gz
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 自定义算子(op)
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
aishipbox op new my_op # 交互向导(questionary)
|
|
66
|
+
cd my_op
|
|
67
|
+
# 把测试数据放入 obs_input/
|
|
68
|
+
aishipbox op run # mock 模式(默认)
|
|
69
|
+
aishipbox op run --obs # 真实 OBS(读取 .env)
|
|
70
|
+
aishipbox op run --debug # 等 VS Code 在端口 5678 附加
|
|
71
|
+
aishipbox op debug # 生成 .vscode/launch.json
|
|
72
|
+
aishipbox op download <package> # 下载依赖 wheel 到 dependency/,写入 requirements.txt
|
|
73
|
+
aishipbox op pack # 打 program_package/<id>.tar
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
非交互模式(脚本/CI/coding agent)—— 带 `--yes` 即可,未提供的字段用默认值填充,scaffold 后再编辑 `manifest.yml`:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
aishipbox op new my_op --yes # 全默认,最省事
|
|
80
|
+
aishipbox op new my_op --yes \ # 也可只覆盖关心的字段
|
|
81
|
+
--category 数据转换 --modal IMAGE --auto-data-loading=true
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
> 非交互环境下漏掉 `--yes` 会立即报错(而非卡在向导上),提示改用 `--yes`。
|
|
85
|
+
|
|
86
|
+
> 📖 **算子完整开发流程见 [OP_USAGE.md](OP_USAGE.md)** —— 安装 → 新建 → 实现 → 本地 mock 调试 → 加依赖 → 打包,含交互式与 agent 非交互式两条路径。
|
|
87
|
+
|
|
88
|
+
## 算子两种模式
|
|
89
|
+
|
|
90
|
+
由 `manifest.yml > runtime > auto-data-loading` 控制,op runner 在本地透明 emulate 平台行为。
|
|
91
|
+
|
|
92
|
+
| 模式 | 设置 | 输入 | 输出 | 适用 |
|
|
93
|
+
|---|---|---|---|---|
|
|
94
|
+
| 模式一 | `auto-data-loading: true` | 框架按文件类型构造 DataFrame,**逐文件**调用 PreProcess→Process→PostProcess | 算子返回 DataFrame;mock 模式下汇总写入 `obs_output/result.jsonl` | 单模态、按样本/按文件处理 |
|
|
95
|
+
| 模式二 | `auto-data-loading: false` | 空 DataFrame,算子自行从 `args.obs_input_path` 读取 | 无返回值,算子自行写 `args.obs_output_path` | 多模态、跨样本(如去重)、非标准输出模态 |
|
|
96
|
+
|
|
97
|
+
### 模式一的 DataFrame 形状(按文件扩展名分派)
|
|
98
|
+
|
|
99
|
+
| 扩展名 | DataFrame 列 | 来源 |
|
|
100
|
+
|---|---|---|
|
|
101
|
+
| `.jsonl` | 文件自身字段 | `pd.read_json(..., lines=True)` |
|
|
102
|
+
| `.csv` | 文件自身字段 | `pd.read_csv` |
|
|
103
|
+
| `.parquet` | 文件自身字段 + 系统注入 `file_path` / `file_name` | `pd.read_parquet`(需 pyarrow) |
|
|
104
|
+
| 其他 | 单行 `file_path` + `file_name` | runner 枚举文件 |
|
|
105
|
+
|
|
106
|
+
同一 `obs_input/` 目录禁止混合上述类型 —— runner 会失败并提示改用模式二。多模态请用模式二。
|
|
107
|
+
|
|
108
|
+
## 本地 mock 基础设施
|
|
109
|
+
|
|
110
|
+
`op run` 默认使用 mock 模式,把平台依赖在本地等价模拟:
|
|
111
|
+
|
|
112
|
+
- **`moxing.file`** — 18 个 API:`list_directory` / `copy` / `copy_parallel` / `read` / `write` / `append` / `glob` / `walk` / `stat` / `exists` / `is_directory` / `make_dirs` / `mk_dir` / `remove` / `rename` / `get_size` / `scan_dir` / `File`
|
|
113
|
+
- **`ma_utils.FileLogger.get_logger()`** — 平台标准日志入口,本地返回配置好格式的 stdlib logger
|
|
114
|
+
- **路径解析**:`obs://input/` → `obs_input/`,`obs://output/` → `obs_output/`;**其他 bucket 名**会立即报错(只在两条 mock 路径上保证等价)
|
|
115
|
+
|
|
116
|
+
为了避免 "本地通过、平台失败" 的 API 差异(pandas 1.3 ↔ 2.x、numpy 1 ↔ 2 都有真实破坏性变更),`aishipbox op new` 在新建项目时把平台预置的 `pandas==1.3.5` / `numpy==1.26.4` / `pyarrow==18.0.0` 装到本地 `.venv/`。这些版本来自 `aishipbox/core/config.py` 的 `PLATFORM_PRESET_PINS` 常量,**不会**写进 `program_package/dependency/requirements.txt` —— 那个文件会被打入算子包,平台 `pip install --no-index` 不应该被要求重装已预置的包。
|
|
117
|
+
|
|
118
|
+
## 依赖下载
|
|
119
|
+
|
|
120
|
+
`aishipbox op download <package>` 下载单个包的 wheel(不含其依赖的依赖,`--no-deps`)到 `program_package/dependency/`,并自动把解析出的版本写入 `requirements.txt`:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
aishipbox op download requests
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
按 `manifest.yml > runtime > cpu-arch` 选择目标平台(`ARM` → `manylinux2014_aarch64`,`X86` → `manylinux2014_x86_64`),固定 Python 3.10(op 托管运行时),与开发机平台无关 —— 在 macOS/Windows 上也能下到正确的 Linux wheel。平台预置包(`PLATFORM_PRESET_PINS`)会被拒绝下载。
|
|
127
|
+
|
|
128
|
+
## 项目结构
|
|
129
|
+
|
|
130
|
+
每个项目都包含 `.aishipbox.toml`(项目类型与运行时标记)、`AGENTS.md`(AI agent 专属操作指南)、独立的 `.venv/`(algo: 3.9, op: 3.10)。
|
|
131
|
+
|
|
132
|
+
算子项目额外包含:
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
my_op/
|
|
136
|
+
├── manifest.yml # 算子元数据(id/name/modal/runtime/arguments/labels...)
|
|
137
|
+
├── program_package/
|
|
138
|
+
│ ├── process.py # 必填,算子主实现
|
|
139
|
+
│ ├── dependency/
|
|
140
|
+
│ │ └── requirements.txt # 平台预置之外的依赖
|
|
141
|
+
│ └── install.sh.example # 自定义安装步骤模板
|
|
142
|
+
├── obs_input/ obs_output/ # 本地 mock 输入/输出
|
|
143
|
+
├── .env.example # --obs 模式凭据模板
|
|
144
|
+
├── AGENTS.md .aishipbox.toml .gitignore
|
|
145
|
+
└── .venv/ # uv venv --python 3.10
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
打包结果:`program_package/<id>.tar`(未压缩)。归档内部按平台规范嵌套于 `<id>/` 之下。
|
|
149
|
+
|
|
150
|
+
## 文档
|
|
151
|
+
|
|
152
|
+
- 设计:`docs/superpowers/specs/2026-05-11-aishipbox-design.md`
|
|
153
|
+
- 实施计划:`docs/superpowers/plans/2026-05-11-aishipbox.md`
|
|
154
|
+
- PanguLM 算子手册:https://support.huaweicloud.com/usermanual-pangulm/pangulm_04_0043.html
|
|
155
|
+
- MoXing API:https://support.huaweicloud.com/usermanual-standard-modelarts/modelarts_11_0001.html
|
|
156
|
+
|
|
157
|
+
## 开发
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
uv sync # 装运行 + dev 依赖
|
|
161
|
+
uv run pytest # 单元测试(~100 个)
|
|
162
|
+
uv run pytest -m integration # 端到端(需要 uv 取得 Python 3.9/3.10)
|
|
163
|
+
uv run pytest tests/op/test_runner.py -v # 单文件
|
|
164
|
+
uv tool install --reinstall . # 重装全局 aishipbox(从当前源码)
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
离线环境跑集成测试:`UV_PYTHON_DOWNLOADS=never uv run pytest -m integration`,集成测试会自行 skip 而不是 hang。
|
|
168
|
+
|
|
169
|
+
测试分层:
|
|
170
|
+
- **单元** —— `tests/algo/` `tests/op/` `tests/core/`:纯逻辑,无 venv
|
|
171
|
+
- **集成** —— `tests/integration/`:通过 `uv venv --python <ver>` 起真实项目 venv 跑完整 `new → run → pack`
|