很高兴,收到了一份新款 OrangePi AIpro 开发板,这是香橙派第一次与华为昇腾合作,使用昇腾系列 AI 处理器来设计这款高性价比的 AI 开发板。这块开发板不仅性能强大,还支持丰富的硬件接口,为AI开发者提供了一个理想的实验平台。作为一名会点AI的软件工程师,我迫不及待地想要尝试这款设备,将其应用到实际项目中。^____^
OrangePi AIpro 开发板简介 OrangePi AIpro 拥有8-12 TOPS(每秒万亿次操作)的AI算力,就像你拥有了一台超级计算机,可以快速处理各种复杂的AI任务,比如识别图像、分析视频等。无论是开发智能家居、智能安防,这款开发板都能轻松胜任。其次, AIpro 还配备了8GB或16GB的高速内存,这意味着你可以运行更多、更复杂的AI应用程序,体验流畅的性能。即使是较大规模的数据处理和深度学习模型训练,这款开发板也能轻松应对,毫不费力。
此外,OrangePi AIpro 提供了许多便捷的接口,支持双HDMI输出,能够连接两个4K高清显示屏,带来更广阔的视觉体验;千兆网口保证你在大数据传输和实时联网应用中享有快速、稳定的网络连接;Wi-Fi 5和蓝牙4.2让你可以随时随地进行无线连接,非常适合物联网项目;多种USB接口和Type-C支持高速数据传输,连接外部设备更加方便;M.2插槽支持大容量SSD硬盘,为你提供更多存储空间,存储和读取数据速度更快。
远程连接及相关设置 这次收到的 OrangePi AIpro 开发板带了一张TF卡,内置了官方的 Ubuntu 系统,省去了很多烧录带来的麻烦,所以烧录这部分就略过了,如果大家对烧录系统到 TF 卡以及烧录到 SATA SSD 的过程,可以参考我的这篇博客。
OrangePi Ai Pro 开箱及镜像烧录指南
第一次使用开发板,链接wifi到开发板是我使用开发板必不可少的操作,这样就可以使用 SSH、VNC 等工具来对开发板进行操作,省去了每次使用时需要链接开发板到显示器的步骤。
至于连接工具,官方是有提供 MobaXterm 安装包的,但我更习惯使用 XShell,这里就使用 XShell 进行连接。配置好我们的 SSH 连接信息,点击连接即可进行连接。
为了避免算力恐慌的问题,这里我们刷入官方的“超频”固件,据说这款固件是从CANN软件层面进行优化,将我们的 OrangePi AIpro 开发板从8T的算力优化到了8~12T的算力,但是能不能到12T似乎是个随机数,不同的板子的上限貌似不同 (^____^)。
使用 Xftp 将最新的固件文件 Ascend310B-firmware-7.3.t10.0.b528-rc-signed-opiaipro-12t-1.6ghz-20240605.run传输到我们的开发板上,然后对固件进行升级。
给固件权限
chmod +x Ascend310B-firmware-7.3.t10.0.b528-rc-signed-opiaipro-12t-1.6ghz-20240605.run
运行固件
./Ascend310B-firmware-7.3.t10.0.b528-rc-signed-opiaipro-12t-1.6ghz-20240605.run --full 1.
升级后断电重启即可体验到8~12T的算力啦!
开放 JupyterLab 端口 为了更为方便的在我的电脑上使用 OrangePi AIpro 的环境来调试 AI 模型,这里配置并开放 JupyterLab 的访问端口,从而使得我的电脑可以访问到 OPI AIpro 的 JupyterLab。(如果你想得到一个可以随时使用 OrangePi AIpro 算力的 JupyterLab,完全可以向我一样,打开 JupyterLab 的端口,然后搭配内网穿透服务,风扇开到最大,这样就可以得到一个带有算力资源且随时可以敲代码的网页服务。)
安装防火墙 首先,我们需要确保系统的安全性。防火墙是保护系统免受未经授权访问的重要工具。我们需要先安装防火墙:
sudo apt install firewalld 1. 启动防火墙并开放端口 安装完成后,我们需要启动防火墙并确保它在每次系统启动时自动运行。同时,为了方便后续访问 Jupyter Notebook,我们还需要开放 8888 端口。以下是具体步骤:
切换到 root 用户
su root
启动防火墙并设置开机自启
sudo systemctl start firewalld sudo systemctl enable firewalld
开放 8888 端口,允许通过该端口进行访问
firewall-cmd --add-port=8888/tcp --permanent
重新加载防火墙配置
sudo firewall-cmd --reload 1.
通过这些步骤,我们已经成功启动了防火墙,并开放了 8888 端口,为我们通过浏览器访问 Jupyter Notebook 提供了便利。
创建启动 Jupyter Notebook 的脚本 为了更加方便地启动 Jupyter Notebook,我们可以创建一个启动脚本,从而简化启动过程,还可以自动设置环境变量,确保 Jupyter Notebook 能够正常运行。以下是脚本的具体内容:
. /usr/local/Ascend/ascend-toolkit/set_env.sh export PYTHONPATH=/usr/local/Ascend/thirdpart/aarch64/acllite:$PYTHONPATH
if [ # -eq 1 ]; then jupyter lab --ip 1 --port 8888 --allow-root --no-browser else jupyter lab --ip 0.0.0.0 --port 8888 --allow-root --no-browser fi 1. 2.
将以上内容保存为 start_notebook_all_ports.sh 文件。
赋予脚本运行权限 为了使脚本能够执行,我们需要赋予它运行权限:
chmod +x start_notebook_all_ports.sh 1. 运行脚本 现在,我们可以运行这个脚本来启动 Jupyter Notebook:
./start_notebook_all_ports.sh 1. 运行这个脚本后,你可以在浏览器中通过开发板的 IP 地址和 8888 端口访问 Jupyter Notebook。例如,如果开发板的 IP 地址是 192.168.1.100,那么你可以在浏览器中输入 http://192.168.1.100:8888 来访问,我这里是 192.168.8.131。
获取 Jupyter Notebook Token 为了确保 Jupyter Notebook 的安全性,每次启动时都会生成一个访问令牌(Token)。我们可以通过以下命令来获取这个令牌:
jupyter server list 1. 将输出中的 Token 复制到浏览器中,即可成功登录 Jupyter Lab。
成功打开 Jupyter Lab 成功打开 Jupyter Lab 后,你可以开始在 OrangePi AIpro 开发板上进行 AI 项目的开发与实验。这款开发板的强大性能和丰富接口将大大提升你的开发效率和体验。
通过以上步骤,我们就可以随时可以在 OrangePi AIpro 开发板上进行 AI 开发和实验。
搭建卡通图像生成服务 安装 python-aclite 等依赖包 打开 ~/.bashrc 并在最后添加下面内容,并 source ~/.bashrc 使其生效:
export CPU_ARCH=arch
export THIRDPART_PATH={CPU_ARCH} #代码编译时链接第三方库
export PYTHONPATH=PYTHONPATH #设置pythonpath为固定目录
export INSTALL_DIR=${HOME}/Ascend/ascend-toolkit/latest #CANN软件安装后文件存储路径
获取ascend公共文件,并拷贝到第三方依赖文件夹:
cd {THIRDPART_PATH} cp -r {THIRDPART_PATH}
然后拷贝 python acllite 库到三方依赖文件夹就行了:
cp -r {THIRDPART_PATH} 1. 体验图片卡通化AI 打开JupyterLab,按照操作手册找到 demo5,找到 main.ipynb 文件,并点击上面的 restart 双箭头,然后样例就开始运行了。
运行后,我们就可以看到卡通化后的图片了。
打造图片卡通化 AI 服务器 但我们想要的不仅仅于此。我想将其打造成网页服务器或者API,这样配合内网穿透服务,我们就可以随时使用我们的 OrangePi AIpro 中所含有的 AI 服务啦!这里我主要使用 flask 来构建一个 OrangePi AIpro 图片卡通化的网页服务。下面是简单实现步骤和代码实现:
为了在上传图片后显示处理后的结果,我们需要在上传和处理图片后,将处理后的图片路径传递给模板,并在模板中显示该图片。
下面是完整的实现步骤:
- 创建 Flask 应用 创建一个新的目录,例如 cartoonization_app,并在其中创建以下文件:
app.py: 主 Flask 应用文件。 templates/: 目录,存放 HTML 模板。 static/: 目录,存放生成的图片。
- 编写 app.py 在 app.py 中编写 Flask 应用:
import os import sys import numpy as np import cv2 from flask import Flask, request, render_template, send_from_directory, redirect, url_for
添加模型路径
path = os.path.dirname(os.path.abspath(file)) sys.path.append(os.path.join(path, "..")) sys.path.append(os.path.join(path, "../../../common/acllite/"))
import acl import acllite_utils as utils import constants as const from acllite_imageproc import AclLiteImageProc from acllite_model import AclLiteModel from acllite_image import AclLiteImage from acllite_resource import AclLiteResource
app = Flask(name) app.config['UPLOAD_FOLDER'] = 'static/uploads' app.config['PROCESSED_FOLDER'] = 'static/processed' os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) os.makedirs(app.config['PROCESSED_FOLDER'], exist_ok=True)
class Cartoonization(object): def init(self, model_path, model_width, model_height): self._model_path = model_path self._model_width = model_width self._model_height = model_height self.device_id = 0 self._dvpp = None self._model = None
def init(self):
self._dvpp = AclLiteImageProc()
self._model = AclLiteModel(self._model_path)
return const.SUCCESS
@utils.display_time
def pre_process(self, image):
image_dvpp = image.copy_to_dvpp()
yuv_image = self._dvpp.jpegd(image_dvpp)
crop_and_paste_image = self._dvpp.crop_and_paste_get_roi(yuv_image, image.width, image.height, \
self._model_width, self._model_height)
return crop_and_paste_image
@utils.display_time
def inference(self, resized_image):
return self._model.execute(resized_image)
@utils.display_time
def post_process(self, infer_output, origin_image):
data = ((np.squeeze(infer_output[0]) + 1) * 127.5)
img = cv2.cvtColor(data, cv2.COLOR_RGB2BGR)
img = cv2.resize(img, (origin_image.width, origin_image.height))
return img
初始化Cartoonization对象
currentPath = os.path.join(path, "..") MODEL_PATH = os.path.join(currentPath, "model/cartoonization.om") MODEL_WIDTH = 256 MODEL_HEIGHT = 256
acl_resource = AclLiteResource() acl_resource.init() cartoonization = Cartoonization(MODEL_PATH, MODEL_WIDTH, MODEL_HEIGHT) ret = cartoonization.init() utils.check_ret("Cartoonization.init ", ret)
@app.route('/') def index(): return render_template('index.html')
@app.route('/upload', methods=['POST']) def upload_file(): if 'file' not in request.files: return 'No file part' file = request.files['file'] if file.filename == '': return 'No selected file' if file: filename = os.path.join(app.config['UPLOAD_FOLDER'], file.filename) file.save(filename)
# 处理图片
image = AclLiteImage(filename)
crop_and_paste_image = cartoonization.pre_process(image)
result = cartoonization.inference([crop_and_paste_image])
processed_image = cartoonization.post_process(result, image)
# 保存处理后的图片
processed_filename = os.path.join(app.config['PROCESSED_FOLDER'], file.filename)
cv2.imwrite(processed_filename, processed_image)
return redirect(url_for('processed_file', filename=file.filename))
@app.route('/processed/') def processed_file(filename): return render_template('result.html', filename=filename)
@app.route('/static/processed/') def send_processed_file(filename): return send_from_directory(app.config['PROCESSED_FOLDER'], filename)
if name == 'main': app.run(debug=True, host="0.0.0.0", port=5000) 1. 2. 3.
- 创建模板 在 templates 目录下创建两个 HTML 文件:
index.html
Image Cartoonization body { font-family: Arial, sans-serif; background-color: #f0f0f0; margin: 0; padding: 20px; } .container { max-width: 600px; margin: 0 auto; background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,0.1); } h1 { text-align: center; margin-bottom: 20px; color: #333; } form { text-align: center; } input[type="file"] { display: none; } .custom-file-upload { border: 1px solid #ccc; display: inline-block; padding: 6px 12px; cursor: pointer; background-color: #f0f0f0; color: #333; border-radius: 4px; } .custom-file-upload:hover { background-color: #e0e0e0; } input[type="submit"] { margin-top: 10px; background-color: #4CAF50; color: white; border: none; padding: 10px 20px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; cursor: pointer; border-radius: 4px; } input[type="submit"]:hover { background-color: #45a049; }Upload an Image to Cartoonize
Choose Fileresult.html
<meta charset="UTF-8">
<title>Processed Image</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f0f0f0;
margin: 0;
padding: 20px;
text-align: center;
}
.container {
max-width: 800px;
margin: 0 auto;
background-color: #fff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
h1 {
color: #333;
}
img {
max-width: 100%;
height: auto;
margin-top: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
a {
display: inline-block;
margin-top: 20px;
padding: 10px 20px;
background-color: #4CAF50;
color: white;
text-decoration: none;
border-radius: 4px;
transition: background-color 0.3s ease;
}
a:hover {
background-color: #45a049;
}
</style>
<div class="container">
<h1>Processed Image</h1>
<img src="转存失败,建议直接上传图片文件 {{ url_for('send_processed_file', filename=filename) }}" alt="Processed Image转存失败,建议直接上传图片文件">
<br>
<a href="/">Upload another image</a>
</div>
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55.
打开浏览器,访问 http://<香橙派IP地址>:5000/,你应该能看到上传图片的表单。上传图片后,处理后的图片将会展示在结果页面上,并提供返回主页的链接以便上传另一张图片。
注意事项 确保 static/uploads 和 static/processed 目录存在并且可写。 根据实际情况修改模型路径和其他配置。 可能需要根据实际情况调整 AclLiteImage 的初始化和使用方法。 使用体验总结 当你收到一款像 OrangePi AIpro 这样强大的开发板时,你不仅仅获得了昇腾系列 AI 处理器的强大性能支持,还拥有了丰富的硬件接口和便捷的开发环境。在使用 OrangePi AIpro 的过程中,我深刻体验到了它为 AI 开发者带来的诸多优势:
强大的计算能力:搭载8-12 TOPS的 AI 算力,OrangePi AIpro 让你能够快速处理复杂的 AI 任务。 丰富的硬件接口:支持双HDMI输出、千兆网口、Wi-Fi 5 和蓝牙 4.2,以及多种 USB 接口和 Type-C,为你的项目提供了灵活多样的连接方式,适合各种物联网和数据传输需求。 完善的昇腾生态:生态系统不仅包括硬件和软件支持,还涵盖了多种工具和资源,极大地丰富了开发者在使用这款开发板时的选择和便利性。特别是昇腾社区的AI案例,给了我这种AI小白很多灵感。
总的来说,这是国产开发板香橙派 OrangePi AIpro 以及国产计算框架 CANN 的应用典范,不仅在性能上有了质的飞跃,而且在使用体验和开发效率上都极大地提升,是两者的巨大进步。唯一的不足可能就是散热问题,也可以说是风扇的问题,风扇调大就会特别响,不过OrangePi AIpro 20T版本好像用到了铜管散热,大大降低了这个问题,希望能兼容一下8T的散热。
©著作权归作者所有:来自51CTO博客作者繁依Fanyi的原创作品,请联系作者获取转载授权,否则将追究法律责任 OrangePi AIpro 浅上手及搭建卡通图像生成多元化AI服务 blog.51cto.com/techfanyi/1…