说明设计停止条件和容器资源配置
This commit is contained in:
parent
30cdd05914
commit
eb7033c496
4 changed files with 85 additions and 26 deletions
86
README.md
86
README.md
|
|
@ -16,6 +16,77 @@ The service listens on port `18765`. The current local deployment is reverse pro
|
|||
|
||||
Traefik only performs TLS termination, compression, and reverse proxying for `npt`; authentication is enforced by this application.
|
||||
|
||||
## Deploying the independent np instance
|
||||
|
||||
`np.lihato.icu` runs independently on `100.64.0.11`. Do not copy the `npt`
|
||||
OIDC values unchanged. In the `np-replica` service of the
|
||||
`docker-compose.yml` deployed on `.11`, use:
|
||||
|
||||
```yaml
|
||||
ports:
|
||||
- "100.64.0.11:18765:18765"
|
||||
environment:
|
||||
NP_AUTH_REQUIRED: 1
|
||||
NP_OIDC_ISSUER: https://auth.lihato.icu/application/o/nupack-account/
|
||||
NP_OIDC_CLIENT_ID: np-replica-web
|
||||
NP_OIDC_REDIRECT_URI: https://np.lihato.icu/auth/callback
|
||||
NP_OIDC_POST_LOGOUT_URI: https://np.lihato.icu/
|
||||
```
|
||||
|
||||
The `NP_OIDC_*` variables belong on the web service (`np-replica`); the
|
||||
worker does not perform browser login. Preserve the existing calculation
|
||||
settings, including `NP_WORKER_CONCURRENCY=16`,
|
||||
`NP_PER_JOB_THREAD_LIMIT=4`, and `NP_NUPACK_CACHE_GB=8.0`.
|
||||
|
||||
After editing the Compose file on `.11`, recreate the web container:
|
||||
|
||||
```bash
|
||||
docker compose up -d --force-recreate np-replica
|
||||
```
|
||||
|
||||
If the deployed image predates the account/OIDC changes, rebuild both
|
||||
application containers instead:
|
||||
|
||||
```bash
|
||||
docker compose up -d --build --force-recreate np-replica np-worker
|
||||
```
|
||||
|
||||
Verify the result:
|
||||
|
||||
```bash
|
||||
curl -I https://np.lihato.icu/
|
||||
curl -I 'https://np.lihato.icu/auth/login?next=%2F'
|
||||
```
|
||||
|
||||
The first response should redirect to `/auth/login?next=%2F`. The second
|
||||
`Location` header must contain all of the following:
|
||||
|
||||
- `client_id=np-replica-web`
|
||||
- `redirect_uri=https%3A%2F%2Fnp.lihato.icu%2Fauth%2Fcallback`
|
||||
- `code_challenge_method=S256`
|
||||
|
||||
If it contains `npt-replica-web` or `npt.lihato.icu`, the `.11` container
|
||||
is still running with the wrong environment and must be recreated.
|
||||
|
||||
## 容器资源配置
|
||||
|
||||
当前 `docker-compose.yml` 面向 64 核 / 64 GB 级别的服务器配置,服务拆成三个容器:
|
||||
|
||||
- `redis`:只保存实时队列、运行状态和会话缓存,限制为 `mem_limit: 3g`。Redis 开启 AOF,数据写入 `./runtime/redis`。
|
||||
- `np-replica`:Web/API 容器,限制为 `mem_limit: 4g`,负责页面、登录、历史记录、任务提交和状态查询。它不应该承担大规模计算。
|
||||
- `np-worker`:后台计算容器,限制为 `mem_limit: 56g`,负责实际 NUPACK 计算。大任务应该由这个容器消耗 CPU 和内存。
|
||||
|
||||
计算相关环境变量需要在 `np-replica` 和 `np-worker` 中保持一致:
|
||||
|
||||
- `NP_WORKER_CONCURRENCY=16`:最多同时执行 16 个后台任务,超过后进入 Redis 队列等待。
|
||||
- `NP_PER_JOB_THREAD_LIMIT=4`:单个任务最多使用 4 个 native 计算线程,同时写入 `OMP_NUM_THREADS`、`OPENBLAS_NUM_THREADS`、`MKL_NUM_THREADS`、`NUMEXPR_NUM_THREADS`、`VECLIB_MAXIMUM_THREADS`、`GOTO_NUM_THREADS`,并设置 `nupack.config.threads`。
|
||||
- `NP_NUPACK_CACHE_GB=8.0`:单个 NUPACK 进程可使用的缓存上限。
|
||||
- `NP_JOB_TTL_SECONDS=3600`:Redis 中实时任务状态的保留时间;长期历史记录写入 SQLite。
|
||||
|
||||
理论上当前峰值为 `16 * 4 = 64` 个 native 计算线程。若机器被压满,优先把 `NP_WORKER_CONCURRENCY` 从 `16` 降到 `8` 或 `4`;如果单任务仍过重,再把 `NP_PER_JOB_THREAD_LIMIT` 从 `4` 降到 `2` 或 `1`。`np-replica` 的内存不建议调高来跑计算,应该把计算压力留给 `np-worker`。
|
||||
|
||||
设计任务默认使用官方行为:固定序列 target 也参与 `tube_design` / `complex_design`。如果确认某些 target 完全固定、只需要展示结果、不需要参与优化,可在页面中把 “固定目标策略” 改为 “剥离固定目标以提速”,这样会减少 off-target 集合和优化搜索量。
|
||||
|
||||
## Endpoints
|
||||
|
||||
- `GET /`
|
||||
|
|
@ -52,18 +123,3 @@ Live jobs and sessions are stored in Redis when `NP_REDIS_URL` is enabled. Accou
|
|||
- For the independent `np` deployment on `100.64.0.11`, set `NP_OIDC_ISSUER=https://auth.lihato.icu/application/o/nupack-account/`, `NP_OIDC_CLIENT_ID=np-replica-web`, `NP_OIDC_REDIRECT_URI=https://np.lihato.icu/auth/callback`, and `NP_OIDC_POST_LOGOUT_URI=https://np.lihato.icu/`.
|
||||
- Redis stores the live queue and login sessions. SQLite WAL at `/data/np-replica.sqlite3` stores users, owned jobs, compressed inputs/results/errors, usage totals, and durable share links.
|
||||
- History and job APIs enforce ownership by the Authentik OIDC subject. Public share links expose only the selected record and can be disabled or given an expiry by its owner.
|
||||
|
||||
|
||||
|
||||
现在 `docker-compose.yml` 面向 64 核 / 64G WSL 服务器的并发策略是:
|
||||
|
||||
- 最多同时跑 16 个任务
|
||||
- 每个任务最多用 4 个计算线程
|
||||
- 后续任务进入队列等待
|
||||
- 每个任务的 NUPACK 缓存上限为 8 GB
|
||||
- 理论上最多占用约 64 个 native 计算线程
|
||||
|
||||
如果后面你发现机器还会被压满,最直接的调法就是在 docker-compose.yml 里继续压:
|
||||
|
||||
- 把 NP_WORKER_CONCURRENCY 改小
|
||||
- 或保持并发不变,把 NP_PER_JOB_THREAD_LIMIT 改成 2 或 1
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ services:
|
|||
image: redis:7.4.8-bookworm
|
||||
container_name: np-redis
|
||||
restart: always
|
||||
mem_limit: 2g
|
||||
mem_limit: 3g
|
||||
command: ["redis-server", "--appendonly", "yes", "--appendfsync", "everysec", "--save", "60", "1"]
|
||||
volumes:
|
||||
- ./runtime/redis:/data
|
||||
|
|
|
|||
|
|
@ -1687,6 +1687,7 @@ A+B</textarea>
|
|||
<label>
|
||||
<span data-i18n="design_stop_condition"></span>
|
||||
<input id="designStopCondition" type="number" value="0.02" min="0.001" max="0.99" step="0.01" />
|
||||
<small class="minor-note" data-i18n="design_stop_condition_hint"></small>
|
||||
</label>
|
||||
<label>
|
||||
<span data-i18n="design_max_time_hours"></span>
|
||||
|
|
@ -1706,8 +1707,8 @@ A+B</textarea>
|
|||
<label>
|
||||
<span data-i18n="design_fixed_target_policy"></span>
|
||||
<select id="designFixedTargetPolicy">
|
||||
<option value="exclude_from_optimization" data-i18n="design_fixed_target_exclude"></option>
|
||||
<option value="include" data-i18n="design_fixed_target_include"></option>
|
||||
<option value="exclude_from_optimization" data-i18n="design_fixed_target_exclude"></option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
|
|
@ -2223,14 +2224,15 @@ A+B</textarea>
|
|||
design_help: "Design 按 NUPACK 的 `Domain -> TargetStrand -> TargetComplex/TargetTube` 关系组织。可先定义 domain 约束,再在链输入中用空格分隔的 domain composition 组装链;也可让某条链继续直接使用整链 IUPAC 约束。",
|
||||
design_guide_btn: "打开 Design 教学",
|
||||
design_stop_condition: "停止条件 f_stop",
|
||||
design_stop_condition_hint: "f_stop 越小越严格,可能极慢;若长时间无法达到该缺陷阈值,设计会持续搜索。",
|
||||
design_max_time_hours: "最大设计时间 (小时)",
|
||||
design_seed_label: "随机种子",
|
||||
design_wobble_label: "Wobble mutations",
|
||||
design_wobble_allow: "允许",
|
||||
design_wobble_prohibit: "禁止",
|
||||
design_fixed_target_policy: "固定目标策略",
|
||||
design_fixed_target_exclude: "剥离出优化",
|
||||
design_fixed_target_include: "参与优化",
|
||||
design_fixed_target_exclude: "剥离固定目标以提速",
|
||||
design_fixed_target_include: "参与优化(官方默认)",
|
||||
design_tab_targets: "Target Tubes",
|
||||
design_tab_hard: "Hard Constraints",
|
||||
design_tab_soft: "Soft Constraints",
|
||||
|
|
@ -2574,14 +2576,15 @@ A+B</textarea>
|
|||
design_help: "Design follows the NUPACK `Domain -> TargetStrand -> TargetComplex/TargetTube` hierarchy. You can define domains first and then compose strands from domain tokens, while still allowing any strand to stay as a whole-strand IUPAC constraint when needed.",
|
||||
design_guide_btn: "Open Design Guide",
|
||||
design_stop_condition: "Stop Condition f_stop",
|
||||
design_stop_condition_hint: "Smaller f_stop values are stricter and can be extremely slow; design keeps searching until this defect threshold is reached.",
|
||||
design_max_time_hours: "Max Design Time (hours)",
|
||||
design_seed_label: "Random Seed",
|
||||
design_wobble_label: "Wobble Mutations",
|
||||
design_wobble_allow: "Allow",
|
||||
design_wobble_prohibit: "Prohibit",
|
||||
design_fixed_target_policy: "Fixed Target Policy",
|
||||
design_fixed_target_exclude: "Exclude from Optimization",
|
||||
design_fixed_target_include: "Include in Optimization",
|
||||
design_fixed_target_exclude: "Exclude Fixed Targets for Speed",
|
||||
design_fixed_target_include: "Include in Optimization (Official Default)",
|
||||
design_tab_targets: "Target Tubes",
|
||||
design_tab_hard: "Hard Constraints",
|
||||
design_tab_soft: "Soft Constraints",
|
||||
|
|
@ -4070,7 +4073,7 @@ A+B</textarea>
|
|||
document.getElementById("designSeed").value = payload.design?.seed ?? 0;
|
||||
document.getElementById("designWobble").value = String(payload.design?.wobble_mutations ?? false);
|
||||
document.getElementById("designMaxTimeHours").value = ((payload.design?.max_time_seconds ?? 0) / 3600);
|
||||
document.getElementById("designFixedTargetPolicy").value = payload.design?.fixed_target_policy ?? "exclude_from_optimization";
|
||||
document.getElementById("designFixedTargetPolicy").value = payload.design?.fixed_target_policy ?? "include";
|
||||
const payloadCompute = Array.isArray(payload.compute) ? payload.compute : [];
|
||||
document.querySelectorAll(".check input").forEach((input) => {
|
||||
input.checked = payloadCompute.includes(input.value);
|
||||
|
|
@ -6176,7 +6179,7 @@ A+B</textarea>
|
|||
document.getElementById("designSeed").value = example.design?.seed ?? 0;
|
||||
document.getElementById("designWobble").value = String(example.design?.wobble_mutations ?? false);
|
||||
document.getElementById("designMaxTimeHours").value = ((example.design?.max_time_seconds ?? 0) / 3600);
|
||||
document.getElementById("designFixedTargetPolicy").value = example.design?.fixed_target_policy ?? "exclude_from_optimization";
|
||||
document.getElementById("designFixedTargetPolicy").value = example.design?.fixed_target_policy ?? "include";
|
||||
document.getElementById("complexesText").value = example.complexes_text;
|
||||
const exampleCompute = Array.isArray(example.compute) ? example.compute : [];
|
||||
document.querySelectorAll(".check input").forEach((input) => {
|
||||
|
|
|
|||
|
|
@ -371,7 +371,7 @@ def parse_design_options(payload):
|
|||
"seed": int(raw.get("seed", 0)),
|
||||
"wobble_mutations": bool(raw.get("wobble_mutations", False)),
|
||||
"max_time_seconds": int(raw.get("max_time_seconds", 0)),
|
||||
"fixed_target_policy": str(raw.get("fixed_target_policy", "exclude_from_optimization")).strip().lower(),
|
||||
"fixed_target_policy": str(raw.get("fixed_target_policy", "include")).strip().lower(),
|
||||
}
|
||||
if options["trials"] < 1 or options["trials"] > 8:
|
||||
raise ValueError("design trials must be between 1 and 8.")
|
||||
|
|
@ -2245,7 +2245,7 @@ EXAMPLE_PAYLOAD = {
|
|||
"seed": 0,
|
||||
"wobble_mutations": False,
|
||||
"max_time_seconds": 0,
|
||||
"fixed_target_policy": "exclude_from_optimization",
|
||||
"fixed_target_policy": "include",
|
||||
},
|
||||
"design_domains": [
|
||||
{"name": "a", "sequence": "N10"},
|
||||
|
|
@ -2307,7 +2307,7 @@ DESIGN_TUBE_EXAMPLE_PAYLOAD = {
|
|||
"seed": 1,
|
||||
"wobble_mutations": False,
|
||||
"max_time_seconds": 0,
|
||||
"fixed_target_policy": "exclude_from_optimization",
|
||||
"fixed_target_policy": "include",
|
||||
},
|
||||
"design_domains": [
|
||||
{"name": "a", "sequence": "N10"},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue