跳至主要内容

使用 Gradio 和 EasyOCR 的 DeepSeek R1 演示项目

在本篇 DeepSeek-R1 教程中,您将学习如何通过将 DeepSeek-R1 与 EasyOCR 和 Gradio 集成来构建一个数学谜题求解应用。
· 12分钟 阅读

使用 AI 探索

在这份动手指南中,我将使用 DeepSeek-R1 模型构建一个集成了 EasyOCR 和 Gradio 的数学谜题求解助手。

我将按步骤讲解如何构建一个功能完善的网页应用,借助 DeepSeek R1 模型出色的推理能力,解决各类数学谜题并生成有用的解题步骤。

如果您只想了解 DeepSeek-R1 的概况,建议查看这篇DeepSeek-R1 概览。若要微调模型,推荐这篇教程:微调 DeepSeek-R1。

DeepSeek-R1 演示项目:概览

为了构建我们的谜题求解助手,我们将依次完成以下步骤:

  • 设置必要的先决条件。
  • 使用优化的配置初始化模型。
  • 利用模型的指令能力定义核心功能。
  • 将各组件集成到用户友好的 Gradio 界面中,便于交互。

步骤 1:先决条件

在开始实现之前,请确保已安装以下工具和库:

  • Python 3.8+
  • PyTorch:用于高效处理深度学习模型。
  • EasyOCR:一个用于从图像中提取文本的 Python 模块。
  • Gradio:用于创建用户友好的网页界面。

运行以下命令安装所需依赖:

!pip install torch gradio pillow easyocr -q

安装完上述依赖后,运行以下导入命令:

Import torch
from PIL import Image
import easyocr
import requests
import json
import gradio as gr

步骤 2:设置 DeepSeek-R1 API

下面的脚本演示了如何与 DeepSeek API 交互以根据用户提示获取响应。请注意,DeepSeek 的 API 与 OpenAI 的格式兼容,并为 API 请求使用一个基础 URL。

您可以直接传入 API 密钥(出于隐私原因不推荐),或者像我一样在 Google Colab 中,使用 Secrets 功能保存 API 密钥。也可以使用环境变量。

# DeepSeek API configuration
DEEPSEEK_API_URL = "https://api.deepseek.com/v1/chat/completions"

# If you're using Colab and storing your key in the Secrets tab:
from google.colab import userdata
API_KEY = userdata.get('SECRET_KEY')

# If you are running this code elsewhere then, replace 'YOUR_API_KEY' with your actual DeepSeek API key. Uncomment the following line of code.
#API_KEY = 'YOUR_API_KEY' 

在本文发布时,DeepSeek 的服务负载较高,性能有所下降——我在运行本项目代码时也遇到了较大困难。在尝试运行本项目代码前,请先查看 DeepSeek 的状态页。

步骤 3:设计核心功能

API 已就绪后,我们可以开始编写功能代码。本节将处理包含逻辑谜题的图片,使用 OCR 提取谜题文本,进行清理,然后发送给 DeepSeek API 求解。我们先看代码,然后再进行讲解。

reader = easyocr.Reader(['en'])

def solve_puzzle(image):
    """Extracts the puzzle from the image and sends it to DeepSeek for solving."""
    try:
        # 1. Save the uploaded image temporarily; EasyOCR uses file paths
        image_path = "uploaded_image.png"
        image.save(image_path)

        # 2. Extract text from the image using EasyOCR
        results = reader.readtext(image_path)
        extracted_text = " ".join([res[1] for res in results])

        # Standardize the text to avoid misinterpretation of "??" as "2?"
        extracted_text = extracted_text.replace('??', '?')
      
        if "?" not in extracted_text:
            extracted_text += "?"

        print("Extracted Text:", extracted_text)  # Debugging output

        # 3. Refine the extracted text to standardize expressions
        refined_text = extracted_text.replace('x', '*').replace('X', '*').replace('=', ' = ').strip()
        print("Refined Text:", refined_text)  # Debugging output

        # 4. Compose the user message with concise instructions
        puzzle_prompt = (
            f"You are an AI specialized in solving puzzles. Analyze the following, identify hidden patterns or rules, and provide the missing value with step-by-step reasoning in text format. Do not return an answer in Latex."
            f"\nPuzzle:\n{refined_text}\n"
            "Format your response strictly as follows:\n"
            "1. **Given Equation**:\n   - (original equations)\n"
            "2. **Pattern Identified**:\n   (explain the hidden logic)\n"
            "3. **Step-by-step Calculation**:\n   - For (input values):\n     (calculation and result)\n"
            "4. **Final Answer**:\n     (Answer = X)"
        )

        messages = [
            {"role": "user", "content": puzzle_prompt}
        ]

        # 5. Optimized API request for faster response
        data = {
            "model": "deepseek-reasoner",
            "messages": messages,
            "temperature": 0,  
            "max_tokens": 100  
        }

        headers = {
            "Authorization": f"Bearer {API_KEY}",
            "Content-Type": "application/json"
        }

        # 6. Send the request to DeepSeek with a timeout
        response = requests.post(DEEPSEEK_API_URL, headers=headers, json=data, timeout=15)

        # 7. Check the result
        if response.status_code == 200:
            try:
                json_resp = response.json()
                return json_resp.get("choices", [{}])[0].get("message", {}).get("content", "Error: No response content.").strip()
            except json.JSONDecodeError:
                return "Error: Invalid JSON response from DeepSeek API."
        else:
            return f"Error: DeepSeek API failed with status code {response.status_code}, Response: {response.text}"
    except requests.exceptions.Timeout:
        return "Error: DeepSeek API request timed out. Please try again."
    except Exception as e:
        return f"Error: {str(e)}"

solve_puzzle() 函数会处理包含逻辑谜题的图像,并借助 OCR 和 R1 模型进行求解。它遵循以下步骤:

  1. 初始化 EasyOCR: 我们首先以英文初始化 EasyOCR 读取器。
  2. 图像处理: 将上传的图像临时保存,并使用 EasyOCR 提取文本。
  3. 文本清理: 对提取文本进行标准化,确保一致性与准确性。
  4. 查询构建: 创建结构化查询,包含整理过的谜题文本以及具体的求解指令。
  5. API 交互: 将查询发送至 DeepSeek API,由其分析并解题。请务必使用 deepseek-reasoner 模型以调用 DeepSeek-R1。若要使用 DeepSeek-V3,请使用 deepseek-chat。同时请留意价格,查看定价页面以获取最新信息。
  6. 响应处理:对 API 响应进行处理,提取并返回解答或相应的错误信息。
  7. 错误处理:函数还会处理诸如超时或意外异常等问题,确保运行稳健。

该流程将 OCR 文本提取与 DeepSeek API 的智能解题相结合。

步骤 4:创建 Gradio 界面

Gradio 使我们能够为应用创建交互式网页界面。下面的代码片段为 solve_puzzle() 函数创建了一个用户友好的 Gradio 网页界面。Gradio 界面接收用户输入并将其传给模型进行验证。

interface = gr.Interface(
    fn=solve_puzzle,
    inputs=gr.Image(type="pil"),
    outputs="text",
    title="Logic Puzzle Solver with EasyOCR & DeepSeek",
    description="Upload an image of a logic puzzle, and the model will solve it for you."
)
interface.launch(debug=True)

上述设置包含三个组件:

  • 输入:一个 gr.Image 组件,用户可在此上传图片。
  • 输出:一个 text 组件,用于显示来自 DeepSeek-R1 的答案。
  • 界面:gr.Interface() 函数 将输入与输出连接起来,启动一个供用户交互的网页应用。

步骤 5:测试应用

让我们用一道兼具数学与逻辑的谜题来测试应用。

观察第一行,您会看到 1 + 4 = 5,或许会认为这只是简单加法。但第二行是 2 + 5 = 12,接着 3 + 6 = 21。您能找出其中的规律并解出 8 + 11 = ?

在 Gradio 界面的右侧,您会看到谜题求解应用已识别出该模式:

使用 gradio 的 deepseek-r1 应用

总结

在本教程中,我们构建了一个结合 DeepSeek R1、OCR 和 Gradio 的数学谜题求解助手,用于解答数学谜题。想要持续了解 AI 最新动态,推荐阅读以下博客:

Aashi Dutt

作者

Aashi Dutt

我是一名 Google Developers 机器学习(生成式 AI)领域的专家、Kaggle 三项专家,以及 Women Techmakers 大使,拥有 3 年以上的技术从业经验。2020 年我共同创办了一家健康科技初创公司,目前在佐治亚理工学院攻读计算机科学硕士,专攻机器学习。

主题