华为实习03-基于MindSpore实现DeepSeek-OCR案例开发
1. 准备工作
第一步 Fork:
https://github.com/mindspore-lab/applications/tree/master
第二步 下载权重:
git clone https://github.com/VovyH/applications.git
或者直接下载,然后
git init
git remote add upstream git@github.com:mindspore-lab/applications.git
第三步 绑定上游仓库
因为 fork 的仓库默认一般只有 master 分支,我们提交到 dev 分支上。所以,我们需要 add 上游仓库。
git remote add upstream git@github.com:mindspore-lab/applications.git
第四步 从上游仓库拉取分支信息
git fetch upstream
第五步 配置公钥私钥
ssh-keygen -t ed25519 -C "xxxxxxxx"
# 验证
ssh -T git@github.com
第六步 切换分支
切换到上游仓库的 dev 分支
git checkout -b dev upstream/dev
第七步 合并代码
上游 dev 分支的代码同步到本地
git pull upstream dev
2. 实现思路
目的: 参考 DeepSeek-OCR 实现,实现基于 MindSpore 下的 DeepSeek-OCR Demo;
注意事项: 需要用到 NPU ,而 NPU 和 Huggingface 上模型的桥梁是 MindSpore NLP 这个库。
NPU 踩过的坑:
CANN : 算子库版本为 8.1 和 MindSpore 版本不匹配,但任务要求你使用 MindSpore NLP == 0.5.1。
NPU:加载模型需要在代码层面先显示设置需要绑定的设备,而不能在模型加载的时候绑定。
速度问题:NPU首次运行会触发 JIT 编译,消耗时间特别长,没有采用二进制缓存机制(set_compile_mode(jit_compile = False))即可。
device_map:不支持 auto,需要显式设置 npu:0。
相关内容: https://blog.csdn.net/weixin_57128596/article/details/158570644?sharetype=blogdetail&sharerId=158570644&sharerefer=PC&sharesource=weixin_57128596&spm=1011.2480.3001.8118
实现思路: 使用 mindnlp 库将 hf 模型算子映射为 MindSpore 算子;
- 导入依赖与环境配置
import os
import re
import mindspore
import mindnlp
from PIL import Image, ImageDraw
from mindnlp.transformers import AutoModel, AutoTokenizer
# 设置运行设备 (Ascend)
mindspore.set_context(mode=mindspore.PYNATIVE_MODE, device_target="Ascend")
- 模型与分词器加载
DeepSeek-OCR 通常基于视觉语言模型架构。使用 AutoModel 时,MindNLP 会接管权重转换。
model_name = "deepseek-ai/DeepSeek-OCR"
# 加载分词器
tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
# 加载模型,指定 MindSpore 的数据类型
model = AutoModel.from_pretrained(
model_name,
ms_dtype=mindspore.bfloat16,
trust_remote_code=True
)
model.set_train(False) # 开启推理模式
- 推理函数实现
这是案例的核心,需处理图像输入并解析模型返回的坐标信息。
def process_ocr(image_path, task_type="OCR", ref_text=""):
# 1. 根据任务类型构建 Prompt
prompts = {
"OCR": "<image>\nFree OCR.",
"Markdown": "<image>\n<|grounding|>Convert the document to markdown.",
"Figure": "<image>\nParse the figure.",
"Locate": f"<image>\nLocate <|ref|>{ref_text}<|/ref|> in the image."
}
prompt = prompts.get(task_type, prompts["OCR"])
# 2. 调用模型进行推理 (MindNLP 封装后的 model.infer 或通用 generate)
# 注意:具体调用接口参考 DeepSeek-OCR 权重内的 modeling_xxx.py
output_text = model.chat(
tokenizer,
image_path=image_path,
prompt=prompt,
)
return output_text
- 结构化结果可视化 (Bounding Box)
DeepSeek-OCR 会返回类似 <|det|>[[x1, y1, x2, y2]]<|/det|> 的坐标,需要进行正则提取并利用 PIL 绘制。
def draw_bboxes(image, text_result):
draw = ImageDraw.Draw(image)
w, h = image.size
# 匹配坐标正则
pattern = re.compile(r"<\|det\|>\[\[(\d+),\s*(\d+),\s*(\d+),\s*(\d+)\]\]<\|/det\|>")
matches = pattern.finditer(text_result)
for match in matches:
coords = [int(c) for c in match.groups()]
# 归一化坐标转换 (模型通常基于 1000x1000)
x1, y1, x2, y2 = coords[0]*w/1000, coords[1]*h/1000, coords[2]*w/1000, coords[3]*h/1000
draw.rectangle([x1, y1, x2, y2], outline="red", width=3)
return image
img_path = "document_sample.png"
res_md = process_ocr(img_path, task="Markdown")
print("--- 转换结果 ---")
print(res_md)
# 寻找图片中的“公章”
res_locate = process_ocr(img_path, task="Locate", ref_text="公章")
annotated_img = draw_bboxes(img_path, res_locate)
annotated_img.show()
更多推荐
所有评论(0)