diff --git a/Dockerfile b/Dockerfile index 3acd1e5..a28975e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,4 +17,7 @@ COPY detect_head_size.py /opt/ COPY patch_ops.py /opt/ COPY patched_ops /opt/patched_ops/ COPY entrypoint.sh /opt/ -RUN chmod +x /opt/entrypoint.sh + +# 在构建时执行 patch_ops(只需要执行一次) +RUN python3 /opt/patch_ops.py && \ + chmod +x /opt/entrypoint.sh diff --git a/README.md b/README.md index fb489b7..97ba738 100644 --- a/README.md +++ b/README.md @@ -57,12 +57,12 @@ entrypoint.sh ↓ 如果 head_size 不在支持列表中,patch vLLM 代码 ↓ -Patch ixformer ops(复制自定义函数并修改 __init__.py) -↓ vllm serve --tokenizer /tmp/fixed_tokenizer ```` +**注意**:Ixformer ops 的 patch 在**镜像构建时**完成,不需要在容器启动时执行。 + --- ## 4. 支持的自动修复场景 @@ -314,6 +314,14 @@ cp /usr/local/corex/lib64/python3/dist-packages/vllm/attention/ops/paged_attn.py 某些模型需要特定的 ixformer 操作函数,如 `gelu_tanh_and_mul`,但这些函数可能不在默认的 ixformer 库中。 +### 补丁时机 + +**重要**:Ixformer ops 的 patch 在**镜像构建时**执行,而不是在容器启动时执行。这意味着: + +- ✅ **性能优化**:容器启动速度更快,不需要每次都执行 patch 操作 +- ✅ **一次构建,多次运行**:patch 操作只在构建镜像时执行一次 +- ✅ **符合最佳实践**:将构建时操作放在 Dockerfile 中,运行时操作放在 entrypoint 中 + ### 通用解决方案 **重要特性**:系统采用**通用扫描机制**,无需每次修改代码: @@ -335,14 +343,14 @@ patched_ops/ └── ... ``` -系统会自动: +系统会在镜像构建时自动: - 扫描所有 `.py` 文件(排除 `__init__.py`) - 复制到 `/usr/local/corex/lib64/python3/dist-packages/ixformer/functions/` - 在 `__init__.py` 中添加对应的 import 语句 ### 补丁逻辑 -系统会自动执行以下操作: +系统会在镜像构建时自动执行以下操作: 1. **扫描源目录** ```bash @@ -367,11 +375,15 @@ patched_ops/ 4. **自动备份** 在修改前会自动备份原始的 `__init__.py` 文件为 `__init__.py.backup` -### 日志示例 +### 构建时日志示例 **成功的批量补丁操作** ``` -[entrypoint] patching ixformer ops... +Step 4/8 : COPY patched_ops /opt/patched_ops/ + ---> Using cache + ---> 1234567890ab +Step 5/8 : RUN python3 /opt/patch_ops.py && chmod +x /opt/entrypoint.sh + ---> Running in 9876543210fe [patch_ops] Starting ixformer ops patch... [patch_ops] Found 3 ops file(s): gelu_tanh_and_mul.py, another_op.py, third_operation.py [patch_ops] Backed up /usr/local/.../__init__.py to /usr/local/.../__init__.py.backup @@ -381,11 +393,14 @@ patched_ops/ [patch_ops] Added 3 import statement(s) to /usr/local/.../__init__.py [patch_ops] Successfully patched ixformer ops [patch_ops] Patch completed successfully + ---> Removed intermediate container + ---> abcdef123456 ``` -**重复运行(已存在import)** +**重复构建(已存在import)** ``` -[entrypoint] patching ixformer ops... +Step 5/8 : RUN python3 /opt/patch_ops.py && chmod +x /opt/entrypoint.sh + ---> Running in 1234567890ab [patch_ops] Starting ixformer ops patch... [patch_ops] Found 3 ops file(s): gelu_tanh_and_mul.py, another_op.py, third_operation.py [patch_ops] Backup already exists: /usr/local/.../__init__.py.backup @@ -396,15 +411,6 @@ patched_ops/ [patch_ops] Successfully patched ixformer ops ``` -**目标目录不存在的情况** -``` -[entrypoint] patching ixformer ops... -[patch_ops] Starting ixformer ops patch... -[patch_ops] Target directory not found: /usr/local/corex/lib64/python3/dist-packages/ixformer/functions/ -[patch_ops] Patch failed, but this will not prevent vLLM from starting -[entrypoint] ixformer ops patch failed, but continuing with vllm startup -``` - ### 补丁恢复 如需恢复原始的 `__init__.py` 文件: @@ -415,13 +421,11 @@ cp /usr/local/corex/lib64/python3/dist-packages/ixformer/functions/__init__.py.b ### 容错机制 -与 head_size 检测一样,ixformer ops 补丁也具有完整的容错机制: +由于 patch 在镜像构建时执行,如果构建失败: -- ✅ **源目录不存在不影响启动**:如果源目录不存在,vLLM 仍会正常启动 -- ✅ **目标目录不存在不影响启动**:如果目标目录不存在,vLLM 仍会正常启动 -- ✅ **复制失败不影响启动**:如果复制过程出错,vLLM 仍会正常启动 -- ✅ **修改失败不影响启动**:如果修改 __init__.py 失败,vLLM 仍会正常启动 +- ✅ **构建失败会立即发现**:不会发布有问题的镜像 - ✅ **部分失败不影响整体**:即使某个文件处理失败,其他文件仍会继续处理 +- ✅ **清晰的错误日志**:构建日志会明确显示失败原因 --- @@ -436,13 +440,23 @@ cp /usr/local/corex/lib64/python3/dist-packages/ixformer/functions/__init__.py.b 主要功能: - ✅ 自动修复不兼容的 tokenizer 配置 - ✅ 自动检测并补丁不支持的 head_size -- ✅ 自动补丁 ixformer ops(如 gelu_tanh_and_mul) +- ✅ 自动补丁 ixformer ops(如 gelu_tanh_and_mul)- **在镜像构建时执行** - ✅ 无需修改模型文件,无需修改启动命令 - ✅ 完全透明,不影响正常模型部署 - ✅ **完整的容错机制,确保本来能跑的模型不受影响** ### 启动流程总结 +**镜像构建时**: +``` +复制 patched_ops 文件 +↓ +执行 patch_ops.py(一次) +↓ +补丁 ixformer ops 到目标目录 +``` + +**容器启动时**: ``` 容器启动 ↓ @@ -450,8 +464,6 @@ cp /usr/local/corex/lib64/python3/dist-packages/ixformer/functions/__init__.py.b ↓ 检查并 patch head_size(如需要) ↓ -检查并 patch ixformer ops(如需要) -↓ 启动 vLLM ``` diff --git a/entrypoint.sh b/entrypoint.sh index b8ba2d1..b297031 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -38,10 +38,6 @@ fi echo "[entrypoint] checking model head_size..." python3 /opt/detect_head_size.py || echo "[entrypoint] head_size check failed, but continuing with vllm startup" -# Patch ixformer ops(即使失败也不影响启动) -echo "[entrypoint] patching ixformer ops..." -python3 /opt/patch_ops.py || echo "[entrypoint] ixformer ops patch failed, but continuing with vllm startup" - echo "[entrypoint] starting vllm..." exec vllm serve "$MODEL_DIR" $TOKENIZER_ARG "$@"