AI算法部署及更新
一、算法部署
-
加载算法镜像
如上图所示加载build_final.tar为docker镜像
docker load -i /tar_all/build_final.tar
加载完镜像之后如下图,出现build_finall就算加载镜像成功,记录最后一行的ImageID:
加载算法ai容器:
docker run -it -d --privileged --pid=host --network=host --device /dev/cambricon_dev0 --device /dev/cambricon_ct --device /dev/cambricon_ipcm0 -v /usr/bin/cnmon:/usr/bin/cnmon -v /ai_data:/ai_data --name ai --restart always <ImageID>
加载完后使用docker ps查看ai容器是否加载成功如下图:

if [ "$IMAGES_IS_EXIST" -eq 1 ]; then
echo "镜像仓库名 'build_final' 存在。"
# 假设您已经有了镜像 ID,或者您不需要重新加载镜像
# 这里应该有一个获取镜像 ID 的步骤(如果需要的话)
# 尝试获取名为 "build_final" 的镜像的 ID
IMAGE_ID=$(docker images --format '{{.Repository}}:{{.Tag}} {{.ID}}' | grep "build_final:latest" | awk '{print $2}')
# 检查镜像 ID 是否为空
if [ -z "$IMAGE_ID" ]; then
echo "镜像 'build_final' 不存在,执行其他操作(如加载镜像)。"
exit 1
else
echo "镜像 'build_final' 存在,ID 是: $IMAGE_ID"
fi
if ! docker run -it -d --privileged --pid=host --network=host --device /dev/cambricon_dev0 --device /dev/cambricon_ct --device /dev/cambricon_ipcm0 -v /usr/bin/cnmon:/usr/bin/cnmon -v /ai_data:/ai_data --name ai --restart always "$IMAGE_ID" &> /dev/null; then
echo "运行容器失败。"
exit 1
fi
IMAGES_NAME=$(docker images --format '{{.Repository}}' | grep "build_final" | head -n 1)
IMAGES_NAME+="l"
DEVICE_ID=$1
# 判断 DEVICE_ID 是否为空
if [ -z "$DEVICE_ID" ]; then
echo "DEVICE_ID 为空,DEVICE_ID 为空,请手动修改/tmp/pem/encrypted_devices.txt"
else
echo "DEVICE_ID 的值为: $DEVICE_ID"
docker exec -it -e DEVICE_ID="$DEVICE_ID" ai bash -c "echo '正在修改/tmp/pem/encrypted_devices.txt' && echo \"\$DEVICE_ID\" > /tmp/pem/encrypted_devices.txt"
fi
# 输出修改后的镜像名称
echo "Modified image name: $IMAGES_NAME"
# 更新配置文件
/tar_all/excuate/update_and_back.sh "$IMAGES_NAME" "$IMAGES_NAME" # 替换 some_other_parameter 为实际需要的参数
else
echo "镜像仓库名 'build_final' 不存在,加载镜像。"
if ! docker load -i /tar_all/build_final.tar &> /dev/null; then
echo "加载镜像失败。"
exit 1
fi
# 获取加载的镜像的 ID(这里需要修改 load_image 函数以返回 ID)
IMAGE_ID=$(docker images --format '{{.Repository}}:{{.Tag}} {{.ID}}' | grep "build_final:latest" | awk '{print $2}')
if [ -z "$IMAGE_ID" ]; then
echo "加载镜像失败,无法获取镜像 ID。"
exit 1
fi
if ! docker run -it -d --privileged --pid=host --network=host --device /dev/cambricon_dev0 --device /dev/cambricon_ct --device /dev/cambricon_ipcm0 -v /usr/bin/cnmon:/usr/bin/cnmon -v /ai_data:/ai_data --name ai --restart always "$IMAGE_ID" &> /dev/null; then
echo "运行容器失败。"
exit 1
fi
IMAGES_NAME=$(docker images --format '{{.Repository}}' | grep "build_final" | head -n 1)
# build_finall
DEVICE_ID=$1
# 判断 DEVICE_ID 是否为空
if [ -z "$DEVICE_ID" ]; then
echo "DEVICE_ID 为空,DEVICE_ID 为空,请手动修改/tmp/pem/encrypted_devices.txt"
else
echo "DEVICE_ID 的值为: $DEVICE_ID"
docker exec -it -e DEVICE_ID="$DEVICE_ID" ai bash -c "echo '正在修改/tmp/pem/encrypted_devices.txt' && echo \"\$DEVICE_ID\" > /tmp/pem/encrypted_devices.txt"
fi
# 输出修改后的镜像名称
echo "Modified image name: $IMAGES_NAME"
# /tar_all/excuate/update_and_back.sh 新版本 旧版本
/tar_all/excuate/update_and_back.sh "$IMAGES_NAME" "$IMAGES_NAME" # 替换 some_other_parameter 为实际需要的参数
fi
更新容器中/home/v1.24/lib.linux-x86_64-3.7/conf.yaml和/home/v1.24/lib.linux-x86_64-3.7/baseConfig.yaml
脚本:update_and_back.sh ,根据需求进行修改
#!/bin/bash
## 传入算法包的名称,例:v1.24 chmod +x update_and_back.sh ./update_and_back.sh v1.24 1.5
AL_NEW_NAME=$1 # bulid_final
#算法版本,例:1.5
AL_VERSION=$2 # bulid_finall
if [ -z "$AL_NEW_NAME" ] && [ -z "$AL_VERSION" ]; then
exit 0
fi
echo "开始更新算法....."
echo "正在获取本机IP"
HOST_IPS=($(ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -Ev '^(127\.0\.0\.1|172\.17\.0\.1|172\.18\.0\.1)$'))
# 检查是否获取到有效IP
if [ ${#HOST_IPS[@]} -eq 0 ]; then
echo "未找到有效IP地址"
exit 1
fi
echo "获取本机IP完成,IP=$HOST_IPS"
CONFIG_FILE=/tar_all/$AL_VERSION/config.yaml
echo "本地生成config.yaml和baseConfig.yaml"
# 将IP填入config.yaml
for ip in "${HOST_IPS[@]}"; do
# 检查文件是否存在
if [ ! -f "$CONFIG_FILE" ]; then
# 文件不存在,创建并写入内容
cat <<EOL > "$CONFIG_FILE"
{
"local_ip": "http://$ip:8002",
"sql_ip": "$ip",
"port": "13306",
"user": "root",
"pwd": "Dtt@20240625"
}
EOL
else
# 文件已存在,不执行写入操作(可以添加一条消息来通知用户)
echo "配置文件 $CONFIG_FILE 已存在,未进行任何写入操作。"
fi
echo "配置文件已生成在 /tar_all/$AL_VERSION,使用的 IP 地址是 $ip"
done
echo "將config.yaml和baseConfig.yaml放入容器中替換原本有的conf.yaml"
# 判断是否修改baseConfig.yaml
IF_UPDATE_BASHCONFIG=$3
if [ -z "$IF_UPDATE_BASHCONFIG" ]; then
docker cp /tar_all/$AL_VERSION/baseConfig.yaml ai:/home/${AL_NEW_NAME}/lib.linux-x86_64-3.7/
fi
docker cp /tar_all/$AL_VERSION/config.yaml ai:/home/${AL_NEW_NAME}/lib.linux-x86_64-3.7/
echo "更新完成!!!"
echo "重启ai容器"
docker restart ai
二、显卡更新
旧版本:
新版本:
dpkg --remove cambricon-mlu-driver-ubuntu20.04-dkms
dpkg -i /tar_all/cambricon-mlu-driver-dkms_6.2.9-16.ubuntu20.04_amd64.deb
reboot #重启服务器
脚本:
update_driver.sh
#!/bin/bash
# 定义变量
DRIVER_PACKAGE="cambricon-mlu-driver-dkms_6.2.9-16.ubuntu20.04_amd64.deb"
OLD_DRIVER_PACKAGE="cambricon-mlu-driver-ubuntu20.04-dkms"
# 检查是否具有sudo权限
if [ "$(id -u)" -ne 0 ] && [ ! -n "$(sudo -l -U $(id -un) 2>&1 | grep '(ALL)')" ]; then
echo "错误:您没有足够的权限来执行此脚本。请使用sudo运行此脚本。"
exit 1
fi
# 检查旧版本驱动是否已安装
if dpkg -l | grep -q "^ii $OLD_DRIVER_PACKAGE"; then
echo "移除旧版本显卡驱动..."
sudo dpkg --remove $OLD_DRIVER_PACKAGE
if [ $? -ne 0 ]; then
echo "错误:无法移除旧版本显卡驱动。"
exit 1
fi
else
echo "旧版本显卡驱动未安装,无需移除。"
fi
# 检查新版本驱动包是否存在
if [ ! -f "$DRIVER_PACKAGE" ]; then
echo "错误:新版本显卡驱动包 $DRIVER_PACKAGE 不存在。"
exit 1
fi
# 安装新版本显卡驱动
echo "安装新版本显卡驱动..."
sudo dpkg -i /tar_all/$DRIVER_PACKAGE
if [ $? -ne 0 ]; then
echo "错误:无法安装新版本显卡驱动。"
exit 1
else
echo "新版本显卡驱动安装成功。"
fi
# 可选:重启系统以确保新驱动生效(根据需要执行)
# echo "重启系统以确保新驱动生效..."
reboot
三、算法更新
算法更新时按照要求使用,所有的算法更新和文件替换都需要重新启动 ai
容器,并在平台推送。
替换文件:
docker cp /tar_all/文件全称 ai:/home/XXX/lib.linux-x86_64-3.7/ ## XXX为算法存储目录
docker restart ai
脚本:
replace_file.sh
chmod +x replace_file.sh
例子:./replace_file.sh main.cpython-37m-x86_64-linux-gnu.so v1.24
,之后使用 cnmon
查看算法是否正常启动
#!/bin/bash
# 参数检查
if [ $# -lt 2 ]; then
echo "用法:$0 <文件> <容器中存储目录> "
echo "示例:replace_file.sh road_control_new2.cpython-37m-x86_64-linux-gnu.so v1.24"
exit 1
fi
REPLACE_FILE=$1
algorithm=$2
if [ ! -f "/tar_all/$REPLACE_FILE" ]; then
echo "警告:文件 '/tar_all/$REPLACE_FILE' 不存在!"
exit 1
fi
docker cp /tar_all/$REPLACE_FILE ai:/home/$algorithm/lib.linux-x86_64-3.7/
docker restart ai
替换lib.linux-x86_64-3.7目录下的所有文件,打包的文件一般 .tar 文件
docker cp 1.61.tar ai:/home/v1.24/
docker attach ai 或 docker exec -it ai /bin/bash # 进入容器
cd /home/v1.24/
tar -tf 1.61.tar #查看是否只有lib*目录若有其他目录为lib*的上级目录解压后使用 mv XXX/lib.linux-x86_64-3.7 ./
tar -zxvf 1.61.tar -C ./
修改config.yaml
vi /home/XXX/lib.linux-x86_64-3.7/config.yaml #xxx为算法存放目录名
{
"local_ip": "http://<服务器IP>:8002",
"sql_ip": "<服务器IP>",
"port": "13306",
"user": "root",
"pwd": "Dtt@20240625"
}
使用CTRL+P+Q键退出容器
docker restart ai ## 重启ai容器,并在平台推送
脚本:replace_lib.sh
chmod +x replace_lib.sh
示例:./replace_lib.sh 1.61.tar v1.24
#!/bin/bash
# 参数检查
if [ $# -lt 2 ]; then
echo "用法:$0 <tar文件> <默认目录> <模式1:目录1> <模式2:目录2> ..."
echo "示例:./replace_lib.sh 1.61.tar v1.24"
exit 1
fi
REPLACE_LIB=$1
algorithm=$2
if [ ! -f "$REPLACE_LIB"]; then
echo "$REPLACE_LIB文件找不到!!"
exit 1
fi
# 获取当前服务器IP
ip=($(ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -Ev '^(127\.0\.0\.1|172\.17\.0\.1|172\.18\.0\.1)$'))
docker cp /tar_all/$REPLACE_LIB ai:/home/$algorithm/
docker exec ai bash -c "echo '开始解压$REPLACE_LIB文件' && tar -zxvf /home/$algorithm/$REPLACE_LIB -C /home/$algorithm/ && echo '$REPLACE_LIB文件解压完成,替换成功' && echo '开始修改config.yaml文件'"
#docker exec ai bash -c "cat <<'EOL' > '$CONFIG_FILE'
#{
# \"local_ip\": \"http://$ip:8002\",
# \"sql_ip\": \"$ip\",
# \"port\": \"13306\",
# \"user\": \"root\",
# \"pwd\": \"Dtt@20240625\"
#}
#EOL"
docker exec ai bash -c "
# 先备份原文件(如果不存在则忽略错误)
[ -f '/home/$algorithm/lib.linux-x86_64-3.7/config.yaml' ] && cp '/home/$algorithm/lib.linux-x86_64-3.7/config.yaml' '/home/config.yaml.bak' || true
# 使用heredoc写入新内容
cat <<'EOL' > '/home/$algorithm/lib.linux-x86_64-3.7/config.yaml'
{
\"local_ip\": \"http://$ip:8002\",
\"sql_ip\": \"$ip\",
\"port\": \"13306\",
\"user\": \"root\",
\"pwd\": \"Dtt@20240625\"
}
EOL
# 验证文件内容
echo '文件已更新,备份文件为: config.yaml.bak' && echo '开始删除$REPLACE_LIB' && rm /home/$algorithm/$REPLACE_LIB"
echo "lib.linux-x86_64-3.7目录下的文件全部替换完成,config.yaml修改完成"
docker restart ai