Appearance
如何使用免费算力部署DeepSeek-OCR模型
前言
DeepSeek-OCR是一个强大的开源OCR模型,但官方部署教程强依赖CUDA环境,Mac用户无法直接运行。本教程通过Google Colab的免费GPU资源,实现零成本部署和试用。
为什么选择Colab
部署限制:
- 强依赖CUDA 11.8+环境
- 需要支持Flash Attention 2.7.3
- 模型文件约6.7GB
- Mac系统不支持本地CUDA
Colab优势:
- 免费T4 GPU(16GB显存)
- 预装CUDA 11.8环境
- 无需本地配置
- 云端存储和下载
部署步骤
第一步:启用GPU运行时
- 访问 Google Colab
- 登录Google账号,创建新笔记本
- 配置GPU(必须):
- 点击"运行时" → "更改运行时类型"
- 硬件加速器选择"T4 GPU"
- 点击"保存"
第二步:一键安装和部署
将以下完整代码粘贴到Colab代码单元格中,按Shift + Enter运行:
python
# ========================================
# DeepSeek-OCR Google Colab 安装和运行脚本
# 带Markdown输出格式优化
# ========================================
# 第一步:检查GPU
print("=== 检查GPU信息 ===")
!nvidia-smi
# 第二步:安装依赖
print("\n=== 开始安装依赖包 ===")
# 安装PyTorch
!pip install torch==2.6.0 torchvision==0.21.0 torchaudio==2.6.0 --index-url https://download.pytorch.org/whl/cu118
# 安装transformers和其他基础依赖
!pip install transformers==4.46.3 tokenizers==0.20.3 einops addict easydict accelerate
# 安装Flash Attention
!pip install flash-attn==2.7.3 --no-build-isolation
print("✓ 依赖安装完成!")
# 第三步:下载模型
print("\n=== 下载DeepSeek-OCR模型 ===")
from transformers import AutoModel, AutoTokenizer
import torch
import re
from datetime import datetime
model_name = 'deepseek-ai/DeepSeek-OCR'
print("正在下载tokenizer...")
tokenizer = AutoTokenizer.from_pretrained(
model_name,
trust_remote_code=True
)
print("正在下载模型(约6.7GB,需要几分钟)...")
model = AutoModel.from_pretrained(
model_name,
trust_remote_code=True,
torch_dtype=torch.bfloat16,
device_map="auto"
)
print("✓ 模型加载完成!")
# ========================================
# DeepSeek-OCR 完整版本
# 包含模型加载 + 简化的提示词调用
# ========================================
import re
from datetime import datetime
# ========================================
# 步骤1:检查并加载模型
# ========================================
def check_and_load_model():
"""检查模型是否已加载,如果没有则加载"""
global model, tokenizer
try:
# 检查模型是否已经存在
_ = model
_ = tokenizer
print("✓ 模型已就绪!")
return True
except NameError:
print("⚠️ 模型未加载,开始加载...")
print("(如果是首次运行,需要下载约6.7GB模型,请耐心等待)")
from transformers import AutoModel, AutoTokenizer
import torch
model_name = 'deepseek-ai/DeepSeek-OCR'
print("正在加载tokenizer...")
tokenizer = AutoTokenizer.from_pretrained(
model_name,
trust_remote_code=True
)
print("正在加载模型...")
model = AutoModel.from_pretrained(
model_name,
trust_remote_code=True,
torch_dtype=torch.bfloat16,
device_map="auto"
)
print("✓ 模型加载完成!")
return True
# 初始化检查
check_and_load_model()
# ========================================
# 步骤2:提示词处理函数
# ========================================
def build_prompt(text):
"""
构建完整的提示词
自动添加 <image>\n 前缀
"""
if text.startswith("<image>"):
return text
else:
return f"<image>\n{text}"
# ========================================
# 步骤3:Markdown处理函数
# ========================================
def parse_ocr_output(raw_output):
"""解析OCR输出,提取统计信息"""
lines = raw_output.split('\n')
stats = {}
for line in lines:
if 'image size:' in line:
stats['image_size'] = line.split('image size:')[1].strip()
elif 'valid image tokens:' in line:
stats['valid_image_tokens'] = int(line.split(':')[1].strip())
elif 'output texts tokens (valid):' in line:
stats['output_text_tokens'] = int(line.split(':')[1].strip())
elif 'compression ratio:' in line:
stats['compression_ratio'] = line.split(':')[1].strip()
# 提取内容
content_lines = []
skip_markers = ['===', 'BASE:', 'PATCHES:', 'image size:', 'valid image tokens:',
'output texts tokens', 'compression ratio:', '正在处理', '%|']
for line in lines:
if not any(marker in line for marker in skip_markers):
content_lines.append(line)
content = '\n'.join(content_lines)
return content, stats
def clean_to_markdown(raw_output, show_bbox=False):
"""转换为Markdown格式"""
content, stats = parse_ocr_output(raw_output)
# 清理标签
if not show_bbox:
content = re.sub(r'<\|ref\|>.*?<\/ref\|>', '', content)
content = re.sub(r'<\|det\|>\[\[.*?\]\]<\/det\|>', '', content)
else:
content = re.sub(r'<\|ref\|>(.*?)<\/ref\|><\|det\|>(\[\[.*?\]\])<\/det\|>',
r'**[\1]**`\2`', content)
content = re.sub(r'\n{3,}', '\n\n', content)
# 构建Markdown
markdown = []
markdown.append("# 📄 OCR识别结果\n")
markdown.append(f"*生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*\n")
if stats:
markdown.append("## 📊 Token统计\n")
markdown.append("| 指标 | 数值 |")
markdown.append("|------|------|")
if 'image_size' in stats:
markdown.append(f"| 图片尺寸 | {stats['image_size']} |")
if 'valid_image_tokens' in stats:
markdown.append(f"| 视觉Token数 | {stats['valid_image_tokens']} |")
if 'output_text_tokens' in stats:
markdown.append(f"| 输出文本Token数 | {stats['output_text_tokens']} |")
if 'compression_ratio' in stats:
markdown.append(f"| 压缩比 | {stats['compression_ratio']}× |")
markdown.append("\n")
markdown.append("## 📝 识别内容\n")
markdown.append(content)
return '\n'.join(markdown), stats
def save_markdown(markdown_text, filename="ocr_result.md"):
"""保存Markdown到文件"""
with open(filename, 'w', encoding='utf-8') as f:
f.write(markdown_text)
print(f"✓ Markdown已保存到: {filename}")
return filename
# ========================================
# 步骤4:核心OCR函数
# ========================================
def ocr_with_markdown(image_file, prompt_text, base_size=1024, show_bbox=False, save_to_file=True):
"""
执行OCR并返回Markdown格式
"""
from PIL import Image
from IPython.display import Markdown, display as ipy_display
import sys
from io import StringIO
# 检查模型
check_and_load_model()
# 构建完整提示词
full_prompt = build_prompt(prompt_text)
# 显示图片
img = Image.open(image_file)
print(f"✓ 图片: {image_file}, 尺寸: {img.size}")
print(f"📝 提示词: {prompt_text[:50]}...")
ipy_display(img)
# 捕获输出执行OCR
print("\n⏳ 正在识别...")
old_stdout = sys.stdout
sys.stdout = captured = StringIO()
try:
model.infer(
tokenizer,
prompt=full_prompt,
image_file=image_file,
output_path="/tmp/output",
base_size=base_size,
image_size=640,
crop_mode=True,
save_results=True,
test_compress=True
)
finally:
sys.stdout = old_stdout
# 获取结果
result = captured.getvalue()
# 如果为空,从文件读取
if not result or len(result) < 100:
try:
with open('/tmp/output/result.mmd', 'r', encoding='utf-8') as f:
result = f.read()
except:
result = "无法获取OCR结果"
print(f"✓ 获取到 {len(result)} 字符的结果")
# 转换为Markdown
markdown_text, stats = clean_to_markdown(result, show_bbox=show_bbox)
# 显示Markdown
print("\n" + "="*60)
print("📄 Markdown格式输出:")
print("="*60)
ipy_display(Markdown(markdown_text))
# 保存并下载
if save_to_file:
filename = save_markdown(markdown_text)
from google.colab import files
print("\n⬇️ 开始下载Markdown文件...")
files.download(filename)
return markdown_text, stats, result
# ========================================
# 步骤5:简化的用户接口
# ========================================
def process_uploaded_image(prompt_text="Convert the document to markdown.", base_size=1024, show_bbox=False):
"""
上传图片并处理
参数:
- prompt_text: 提示词(会自动添加<image>前缀)
- base_size: 分辨率 512/640/1024/1280
- show_bbox: 是否显示坐标
示例:
md, stats, raw = process_uploaded_image("Convert the document to markdown.")
md, stats, raw = process_uploaded_image("Parse the figure.")
md, stats, raw = process_uploaded_image("描述图片内容")
"""
from google.colab import files
print("📤 请上传图片文件...")
uploaded = files.upload()
if not uploaded:
print("❌ 没有上传文件")
return None, None, None
filename = list(uploaded.keys())[0]
print(f"✓ 已上传: {filename}")
return ocr_with_markdown(filename, prompt_text, base_size, show_bbox, True)
def process_existing_image(image_path, prompt_text="Convert the document to markdown.", base_size=1024, show_bbox=False):
"""
处理已上传的图片
参数:
- image_path: 图片路径
- prompt_text: 提示词
- base_size: 分辨率
- show_bbox: 是否显示坐标
示例:
md, stats, raw = process_existing_image("test.jpg", "OCR this image.")
md, stats, raw = process_existing_image("chart.jpg", "Parse the figure.")
"""
return ocr_with_markdown(image_path, prompt_text, base_size, show_bbox, True)
def process_url_image(url, prompt_text="Convert the document to markdown.", base_size=1024, show_bbox=False):
"""
处理网络图片
参数:
- url: 图片URL
- prompt_text: 提示词
- base_size: 分辨率
- show_bbox: 是否显示坐标
示例:
md, stats, raw = process_url_image("https://...", "Describe this image.")
"""
import requests
from PIL import Image
from io import BytesIO
print(f"⬇️ 正在下载图片: {url}")
response = requests.get(url)
img = Image.open(BytesIO(response.content))
temp_path = "/tmp/downloaded_image.jpg"
img.save(temp_path)
print(f"✓ 图片已保存")
return ocr_with_markdown(temp_path, prompt_text, base_size, show_bbox, True)
# ========================================
# 完成提示
# ========================================
print("\n" + "="*60)
print("🎉 DeepSeek-OCR 已就绪!")
print("="*60)
print("\n📖 基础用法(超简单):")
print("\n# 默认:文档转Markdown")
print('md, stats, raw = process_uploaded_image()')
print("\n# 解析图表")
print('md, stats, raw = process_uploaded_image("Parse the figure.")')
print("\n# 描述图片")
print('md, stats, raw = process_uploaded_image("Describe this image in detail.")')
print("\n# 提取表格")
print('md, stats, raw = process_uploaded_image("Parse the table.")')
print("\n# 中文提示词")
print('md, stats, raw = process_uploaded_image("识别图片中的所有文字")')
print("\n" + "="*60)
print("💡 常用提示词参考")
print("="*60)
print("""
文档类:
"Convert the document to markdown." - 文档→Markdown(默认)⭐
"OCR this image." - 通用OCR
"Free OCR." - 简单识别
解析类:
"Parse the figure." - 解析图表
"Parse the table." - 解析表格
"Parse the mathematical formula." - 数学公式
"Parse the chemical formula." - 化学式
"Parse the geometric figure." - 几何图形
描述类:
"Describe this image in detail." - 详细描述
"Provide a dense caption." - 密集标注
中文:
"识别图片中的文字" - 中文OCR
"提取图片中的表格数据" - 中文表格
"描述这张图片的内容" - 中文描述
""")
print("\n" + "="*60)
print("🚀 快速开始")
print("="*60)
print("""
# 步骤1:上传图片并识别(最简单)
md, stats, raw = process_uploaded_image()
# 步骤2:处理已有图片
md, stats, raw = process_existing_image("your_image.jpg", "Parse the table.")
# 步骤3:调整分辨率(可选)
md, stats, raw = process_uploaded_image("OCR this image.", base_size=640)
# 分辨率选择:
# 512 - 简单文档
# 640 - 标准文档(推荐)⭐
# 1024 - 复杂文档
# 1280 - 高清文档
""")
print("\n" + "="*60)
print("✨ 立即开始使用吧!")
print("="*60)预计时间: 5-10分钟(首次运行)
运行成功后,你会看到:
============================================================
🎉 DeepSeek-OCR 已就绪!
============================================================
📖 基础用法(超简单):
# 默认:文档转Markdown
md, stats, raw = process_uploaded_image()
# 解析图表
md, stats, raw = process_uploaded_image("Parse the figure.")
# 描述图片
md, stats, raw = process_uploaded_image("Describe this image in detail.")
# 提取表格
md, stats, raw = process_uploaded_image("Parse the table.")
# 中文提示词
md, stats, raw = process_uploaded_image("识别图片中的所有文字")
============================================================
💡 常用提示词参考
============================================================
文档类:
"Convert the document to markdown." - 文档→Markdown(默认)⭐
"OCR this image." - 通用OCR
"Free OCR." - 简单识别
解析类:
"Parse the figure." - 解析图表
"Parse the table." - 解析表格
"Parse the mathematical formula." - 数学公式
"Parse the chemical formula." - 化学式
"Parse the geometric figure." - 几何图形
描述类:
"Describe this image in detail." - 详细描述
"Provide a dense caption." - 密集标注
中文:
"识别图片中的文字" - 中文OCR
"提取图片中的表格数据" - 中文表格
"描述这张图片的内容" - 中文描述
============================================================
🚀 快速开始
============================================================
# 步骤1:上传图片并识别(最简单)
md, stats, raw = process_uploaded_image()
# 步骤2:处理已有图片
md, stats, raw = process_existing_image("your_image.jpg", "Parse the table.")
# 步骤3:调整分辨率(可选)
md, stats, raw = process_uploaded_image("OCR this image.", base_size=640)
# 分辨率选择:
# 512 - 简单文档
# 640 - 标准文档(推荐)⭐
# 1024 - 复杂文档
# 1280 - 高清文档
============================================================
✨ 立即开始使用吧!
============================================================三种使用方式
安装完成后,在新的代码单元格中使用以下任一方式:
方式1:上传本地图片(推荐)
python
# 默认:文档转Markdown
md, stats, raw = process_uploaded_image()
# 解析图表
md, stats, raw = process_uploaded_image("Parse the figure.")
# 解析表格
md, stats, raw = process_uploaded_image("Parse the table.")
# 中文提示词
md, stats, raw = process_uploaded_image("识别图片中的所有文字")方式2:使用网络图片
python
# 从URL加载图片
md, stats, raw = process_url_image("https://example.com/document.jpg")
# 指定提示词
md, stats, raw = process_url_image(
"https://example.com/chart.jpg",
"Parse the figure."
)方式3:处理已上传的图片
python
# 如果图片已在Colab环境中
md, stats, raw = process_existing_image(
"your_image.jpg",
"Convert the document to markdown."
)分辨率模式说明
根据文档复杂度选择base_size参数:
| 模式 | base_size | 适用场景 | 速度 |
|---|---|---|---|
| Tiny | 512 | 简单文本 | 最快 |
| Small | 640 | 标准文档 | 快 |
| Base | 1024 | 复杂表格/公式 | 中等 |
| Large | 1280 | 高清扫描文档 | 慢 |
使用示例:
python
# 简单文档,使用低分辨率
md, stats, raw = process_uploaded_image(base_size=512)
# 复杂文档,使用高分辨率
md, stats, raw = process_uploaded_image(base_size=1024)查看和下载结果
处理完成后,Markdown文件会自动下载到本地。你也可以手动查看:
python
# 查看输出目录
!ls -lh /tmp/output/
# 读取Markdown结果
with open('/tmp/output/result.mmd', 'r', encoding='utf-8') as f:
content = f.read()
print(content)
# 手动下载结果
from google.colab import files
files.download('/tmp/output/result.mmd')注意事项
免费额度限制
Colab免费版有使用时间限制:
- 连续运行时间:约12小时
- 每日使用时长:8-12小时
- GPU类型:T4(16GB显存)
保存结果
记得下载OCR结果,因为Colab环境会定期重置。
GPU掉线
如果显示"GPU后端已崩溃",重新运行第二步的完整安装脚本即可。
常见问题
Q: 提示"CUDA out of memory"怎么办?
降低分辨率,使用base_size=512或base_size=640:
python
md, stats, raw = process_uploaded_image(base_size=512)Q: 下载模型很慢?
这是正常的,模型有6.7GB,首次下载需要耐心等待。Colab已配置Hugging Face镜像加速。
Q: 能处理PDF吗?
需要先把PDF转成图片。安装pdf2image库:
python
!apt-get install -y poppler-utils
!pip install pdf2image
from pdf2image import convert_from_path
# 上传PDF
from google.colab import files
uploaded = files.upload()
pdf_file = list(uploaded.keys())[0]
# 转换PDF为图片
images = convert_from_path(pdf_file)
# 处理第一页
images[0].save('/tmp/page1.jpg')
md, stats, raw = process_existing_image('/tmp/page1.jpg')
# 批量处理所有页
results = []
for i, img in enumerate(images):
img.save(f'/tmp/page{i+1}.jpg')
md, stats, raw = process_existing_image(f'/tmp/page{i+1}.jpg')
results.append(md)
print(f"完成第{i+1}页")Q: 识别结果不准确?
尝试以下优化:
- 提高
base_size到1024或1280 - 使用更精确的提示词(参考上面的提示词表)
- 确保图片清晰,避免模糊或倾斜
Q: 可以批量处理吗?
可以,使用循环处理多张图片:
python
# 上传多张图片
from google.colab import files
uploaded = files.upload()
results = []
for i, filename in enumerate(uploaded.keys()):
print(f"\n处理第{i+1}张: {filename}")
md, stats, raw = process_existing_image(filename)
results.append(md)
# 保存每张结果
with open(f'/tmp/result_{i+1}.md', 'w', encoding='utf-8') as f:
f.write(md)
print(f"\n完成,共处理{len(results)}张图片")
# 下载所有结果
for i in range(len(results)):
files.download(f'/tmp/result_{i+1}.md')完整工作流示例
以下是一个完整的使用流程:
python
# 1. 上传图片并识别(默认:文档转Markdown)
md, stats, raw = process_uploaded_image()
# 2. 查看统计信息
print(f"图片尺寸: {stats.get('image_size')}")
print(f"视觉Token数: {stats.get('valid_image_tokens')}")
print(f"输出Token数: {stats.get('output_text_tokens')}")
print(f"压缩比: {stats.get('compression_ratio')}")
# 3. 查看识别内容(已经自动显示在输出中)
# 4. Markdown文件已自动下载到本地成本对比
| 项目 | 本地部署 | Colab方案 |
|---|---|---|
| GPU硬件 | ¥5000+ | ¥0(免费) |
| 环境配置 | 2-4小时 | 5分钟 |
| 电力成本 | ¥2/小时 | ¥0 |
| 维护成本 | 需要 | 无需 |
| 适用场景 | 生产环境 | 学习测试 |
进阶学习
完成本教程后,可以继续学习:
- DeepSeek-OCR技术文档 - 深入了解模型架构
- DeepSeek-R1 - 探索推理优化模型
- DeepSeek模型技术 - DeepSeek系列模型
