Docker 常用命令
补充几个命令:
# 查看所有镜像
docker images
# 删除指定镜像
docker rmi <IMAGE_ID>
# 强制删除(正在被容器使用也删)
docker rmi -f <IMAGE_ID>
# 删除多个
docker rmi <ID1> <ID2> <ID3>
# 查看运行中容器大小
docker ps -s
# 停止容器
docker stop opus-zh-en-slim
# 删除容器
docker rm -f opus-zh-en-slim
# 删除镜像
docker rmi -f opus-zh-en-slim
# 清理悬空镜像
docker image prune -f
# 查看磁盘占用
docker system df
# 明细:逐个容器、镜像、卷体积
docker system df -v
# 清理无用镜像+构建缓存(谨慎!)
docker system prune
# 全局清理无用资源(容器/网络/卷/缓存)(-f 不确认,直接删)
docker system prune -f
# 清理所有未使用的镜像、容器、网络、缓存(-a 连同未使用的镜像一起删(不只是悬空镜像))
docker system prune -a
# 删除停止的容器
docker container prune
# 查看构建缓存占用
docker builder du
# 清理构建缓存(能省 几个 GB)
docker builder prune -a -f
引言
在 https://huggingface.co 的国内镜像 https://hf-mirror.com/ 下查看 Helsinki-NLP/opus-mt-zh-en 模型: https://hf-mirror.com/Helsinki-NLP/opus-mt-zh-en,还有源码:https://hf-mirror.com/Helsinki-NLP/opus-mt-zh-en/tree/main
Docker 安装opus-mt-zh-en
切换到root账户,进入用户根目录,创建Dockerfile文件:
# 切换到root账户
su - root
# 进入用户根目录
cd /root
# 创建Dockerfile文件
touch Dockerfile.opus-zh-en
Dockerfile.opus-zh-en写入内容:
FROM quay.io/centos/centos:stream9-minimal
# 阿里云镜像源
RUN sed -e 's|mirror.centos.org|mirrors.aliyun.com|g' \
-e 's|mirror.stream.centos.org|mirrors.aliyun.com|g' \
-i /etc/yum.repos.d/centos* && \
microdnf clean all
# 安装依赖
RUN microdnf install -y git make gcc gcc-c++ cmake python3 python3-pip && \
microdnf clean all
# 阿里pip源
RUN pip3 config set global.index-url https://mirrors.aliyun.com/pypi/simple/
# 安装必装依赖
RUN pip3 install --no-cache-dir transformers sentencepiece sacremoses torch
WORKDIR /app
# 下载模型(国内加速,加长超时时间)
RUN python3 -c "import os; os.environ['HF_ENDPOINT']='https://hf-mirror.com'; os.environ['TRANSFORMERS_TIMEOUT']='300'; from transformers import AutoTokenizer, AutoModelForSeq2SeqLM; tokenizer = AutoTokenizer.from_pretrained('Helsinki-NLP/opus-mt-zh-en'); model = AutoModelForSeq2SeqLM.from_pretrained('Helsinki-NLP/opus-mt-zh-en'); tokenizer.save_pretrained('/app/model'); model.save_pretrained('/app/model')"
CMD ["tail", "-f", "/dev/null"]
构建镜像和创建容器:
# 构建镜像
docker build -t opus-zh-en-slim -f Dockerfile.opus-zh-en .
# 创建容器
docker run -d --name opus-zh-en-slim opus-zh-en-slim
完善容器:
# 进入容器
docker exec -it opus-zh-en-slim /bin/bash
# 进入/app目录
cd /app
# 创建翻译脚本
echo '#!/usr/bin/env python3
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
import sys
if __name__ == "__main__":
text = sys.argv[1]
tokenizer = AutoTokenizer.from_pretrained("/app/model")
model = AutoModelForSeq2SeqLM.from_pretrained("/app/model")
inputs = tokenizer(text, return_tensors="pt", padding=True)
outputs = model.generate(**inputs)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
' > /app/translate.py
修改执行权限:
chmod +x /app/translate.py
# 退出容器
exit
PHP 调用:
$zhText = "你好";
// 翻译汉译英
$zhText = escapeshellarg($zhText);
$cmd = "docker exec opus-zh-en-slim python3 /app/translate.py {$zhText} 2>/dev/null";
$enText = trim(shell_exec($cmd));
清理 docker 残留缓存、悬空镜像、无用数据
# 清理悬空镜像
docker image prune -f
# 全局清理无用资源(容器/网络/卷/缓存)
docker system prune -f
HuggingFace 模型安装
现在存在的问题是服务器上下载模型文件的速度很慢或者无法下载,我们可以在本地电脑下载模型文件(https://hf-mirror.com/Helsinki-NLP/opus-mt-zh-en/tree/main下的所有文件),然后上传到服务器上。
在root家目录下创建文件夹opus-mt-zh-en,并把下载的源码上传到这里:
mkdir -p /root/opus-mt-zh-en
使用 transformers
不进行量化的写法。
requirements.txt文件:
transformers
torch
sentencepiece
sacremoses
transformers 源码中用 MarianTokenizer 做标点归一化用,MarianTokenizer初始化时会自动尝试导入 sacremoses。
translate.py文件:
#!/usr/bin/env python3
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
import sys
if __name__ == "__main__":
text = sys.argv[1]
tokenizer = AutoTokenizer.from_pretrained("/app/opus-mt-zh-en")
model = AutoModelForSeq2SeqLM.from_pretrained("/app/opus-mt-zh-en")
inputs = tokenizer(text, return_tensors="pt", padding=True)
outputs = model.generate(**inputs)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
Dockerfile文件:
FROM quay.io/centos/centos:stream9-minimal
# 替换阿里云yum源
RUN sed -e 's|mirror.centos.org|mirrors.aliyun.com|g' \
-e 's|mirror.stream.centos.org|mirrors.aliyun.com|g' \
-i /etc/yum.repos.d/centos* && \
microdnf clean all && microdnf makecache
# 仅装python基础,不装gcc、不装torch相关
RUN microdnf install -y python3 python3-pip \
&& microdnf clean all && rm -rf /var/cache/dnf
WORKDIR /app
# 安装运行&转换依赖:无torch、无transformers!
COPY requirements.txt .
RUN pip3 install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
COPY opus-mt-zh-en ./opus-mt-zh-en
COPY translate.py .
RUN chmod +x /app/translate.py
CMD ["tail", "-f", "/dev/null"]
命令:
# 构建
docker build -t opus-zh-en .
# 启动
docker run -d --name translate opus-zh-en
构建后大概在8.5G左右。
执行翻译脚本:
[root@localhost ~]# docker exec translate python3 /app/translate.py '你好'
Hello.
[root@localhost ~]#
可以正常使用。
transformers 动态量化
执行时,内存超限,被kill了。
cat > quantize_dynamic_int8.py << 'EOF'
import torch
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
model_dir = "/app/opus-mt-zh-en"
out_dir = "/app/opus-mt-zh-en-dynamic-int8"
# 加载原始 FP32 模型
tokenizer = AutoTokenizer.from_pretrained(model_dir)
model = AutoModelForSeq2SeqLM.from_pretrained(model_dir).eval()
# 动态量化:仅量化 Linear 层 → 权重 INT8,计算 FP32
qmodel = torch.ao.quantization.quantize_dynamic(
model,
{torch.nn.Linear},
dtype=torch.qint8
)
# 保存量化后的模型
qmodel.save_pretrained(out_dir)
tokenizer.save_pretrained(out_dir)
print("动态 INT8 量化完成:", out_dir)
EOF
python3 quantize_dynamic_int8.py
cat > translate_int8.py << 'EOF'
#!/usr/bin/env python3
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
import sys
if __name__ == "__main__":
text = sys.argv[1]
# 加载动态 INT8 量化模型
tokenizer = AutoTokenizer.from_pretrained("/app/opus-mt-zh-en-dynamic-int8")
model = AutoModelForSeq2SeqLM.from_pretrained("/app/opus-mt-zh-en-dynamic-int8")
inputs = tokenizer(text, return_tensors="pt", padding=True)
outputs = model.generate(**inputs)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
EOF
python3 translate_int8.py “你好”
transformers 静态量化
未尝试。
静态量化 = 权重 + 激活都提前算好量化参数(scale/zero_point),推理时不再动态计算 → 速度更快、理论上更省内存,但要做校准(需要数据)。
静态量化脚本 static_quantize_int8.py:
cat > static_quantize_int8.py << 'EOF'
import torch
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
from torch.ao.quantization import get_default_qconfig, prepare, convert
# 路径
model_dir = "/app/opus-mt-zh-en"
out_dir = "/app/opus-mt-zh-en-static-int8"
# 加载模型
tokenizer = AutoTokenizer.from_pretrained(model_dir)
model = AutoModelForSeq2SeqLM.from_pretrained(model_dir).eval()
# 1. 设置量化配置(静态,x86 CPU 用 fbgemm)
qconfig = get_default_qconfig("fbgemm")
model.qconfig = qconfig
# 2. 融合层(可选但推荐,提速)
# OPUS-MT 是 marian,结构简单,这里只做最基础的
try:
model = torch.quantization.fuse_modules(
model,
[
["encoder.layers.0.self_attn.q_proj", "encoder.layers.0.self_attn.k_proj"],
# 可根据报错增删,不行就注释掉
]
)
except Exception as e:
print("融合跳过:", e)
# 3. 准备量化
model_prepared = prepare(model, inplace=False)
# 4. 校准(必须!静态量化核心,用 10–50 句中文即可)
calibration_texts = [
"你好,今天天气很好",
"我是一名学生",
"机器学习很有趣",
"人工智能改变世界",
"自然语言处理",
"我喜欢编程",
"中国文化博大精深",
"今天吃什么",
"请帮我翻译这句话",
"深度学习"
]
print("校准中...")
for text in calibration_texts:
inputs = tokenizer(text, return_tensors="pt", padding=True)
model_prepared(**inputs)
# 5. 转换为静态 INT8 模型
model_quantized = convert(model_prepared)
# 6. 保存
model_quantized.save_pretrained(out_dir)
tokenizer.save_pretrained(out_dir)
print("静态 INT8 量化完成:", out_dir)
EOF
执行量化:
python3 static_quantize_int8.py
改写 translate.py 加载静态量化模型:
cat > translate.py << 'EOF'
#!/usr/bin/env python3
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
import sys
if __name__ == "__main__":
text = sys.argv[1]
tokenizer = AutoTokenizer.from_pretrained("/app/opus-mt-zh-en-static-int8")
model = AutoModelForSeq2SeqLM.from_pretrained("/app/opus-mt-zh-en-static-int8")
inputs = tokenizer(text, return_tensors="pt", padding=True)
outputs = model.generate(**inputs)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
EOF
测试:python3 translate.py "你好"
CTranslate2 量化
试下来未成功。
docker exec -it translate bash
cd /app
pip install ctranslate2 -i https://pypi.tuna.tsinghua.edu.cn/simple
ct2-opus-mt-converter --help
量化
ct2-transformers-converter \
--model /app/opus-mt-zh-en \
--output_dir /app/opus-mt-zh-en-ct2-int8float32 \
--quantization int8_float32 \
--force
# 或
ct2-opus-mt-converter \
--model_dir /app/opus-mt-zh-en \
--output_dir /app/opus-mt-zh-en-ct2-int8float32 \
--quantization int8_float32 \
--force
脚本
cat > /app/ct2_translate.py << 'EOF'
#!/usr/bin/env python3
import sys
import ctranslate2
import sentencepiece as spm
# 量化模型路径
model_path = "/app/opus-mt-zh-en-ct2-int8float32"
spm_source = "/app/opus-mt-zh-en/source.spm"
spm_target = "/app/opus-mt-zh-en/target.spm"
# 加载分词器 & 模型
sp = spm.SentencePieceProcessor()
sp.load(spm_source)
sp_tgt = spm.SentencePieceProcessor()
sp_tgt.load(spm_target)
# 2核2G最优线程:inter=1, intra=2(不超物理核)
translator = ctranslate2.Translator(
model_path,
device="cpu",
inter_threads=1,
intra_threads=2
)
# 输入中文
text = sys.argv[1]
# 翻译
tokens = sp.encode(text, out_type=str)
results = translator.translate_batch([tokens])
output = sp_tgt.decode(results[0].hypotheses[0])
print(output)
EOF
查看:python3 ct2_translate.py "你好"