DeepSeek-OCR-2实战案例:高校教务系统成绩单PDF自动结构化入库

news2026/3/23 1:14:13
DeepSeek-OCR-2实战案例高校教务系统成绩单PDF自动结构化入库1. 引言从堆积如山的PDF到一键入库每到学期末高校教务处的老师们就要面对一项繁重的工作处理成千上万份学生成绩单PDF文件。这些文件格式各异有的清晰规整有的扫描模糊还有的表格排版复杂。传统的人工录入方式不仅耗时耗力还容易出错。想象一下这样的场景一位教务老师需要将5000份成绩单PDF中的学生信息、课程成绩、学分等数据录入数据库。每份文件平均耗时3分钟总时间就是15000分钟相当于连续工作250个小时。这还不包括核对、纠错的时间。现在有了DeepSeek-OCR-2这一切变得简单多了。这个模型能够智能理解文档内容准确识别各种格式的成绩单并将非结构化的PDF数据转化为结构化的数据库记录。今天我就带大家看看如何用DeepSeek-OCR-2、vLLM推理加速和Gradio前端展示构建一个完整的成绩单自动处理系统。2. DeepSeek-OCR-2不只是文字识别2.1 为什么选择DeepSeek-OCR-2你可能用过传统的OCR工具它们通常只能机械地识别文字位置然后按行输出。但成绩单这种文档往往包含表格、特殊符号、复杂排版传统OCR处理起来效果很差。DeepSeek-OCR-2采用了创新的DeepEncoder V2方法它最大的特点是能够理解图像的含义然后动态重排图像的各个部分。简单来说它不再像传统OCR那样从左到右、从上到下机械扫描而是像人一样先理解这是什么文档然后按照文档的逻辑结构来识别内容。对于成绩单这种结构化文档DeepSeek-OCR-2能够准确识别表格中的行列关系理解表头、数据、总分等不同部分的含义处理扫描模糊、倾斜、阴影等质量问题识别特殊符号和格式如百分号、等级制成绩2.2 技术亮点与性能表现DeepSeek-OCR-2在多项测试中表现优异。它只需要256到1120个视觉标记就能覆盖复杂的文档页面这意味着处理速度快、资源消耗少。在OmniDocBench v1.5评测中它的综合得分达到了91.09%这个成绩相当不错。更重要的是这个模型是开源的我们可以根据自己的需求进行调整和优化。对于高校成绩单这种特定场景我们可以针对性地训练和优化让识别准确率更高。3. 系统架构设计从PDF到数据库的完整流程3.1 整体架构概览我们的成绩单自动处理系统包含三个核心组件PDF文件 → DeepSeek-OCR-2识别 → 数据清洗 → 数据库入库 → Gradio展示 ↑ vLLM加速推理让我详细解释每个环节PDF预处理将上传的PDF文件转换为适合OCR处理的图像格式OCR识别使用DeepSeek-OCR-2识别图像中的文字和表格结构数据清洗对识别结果进行格式化、校验和纠错数据库入库将结构化数据存入MySQL或PostgreSQL数据库前端展示通过Gradio提供友好的用户界面3.2 为什么用vLLM加速vLLM是一个高性能的推理引擎专门为大语言模型设计。虽然DeepSeek-OCR-2不是纯文本模型但vLLM的优化技术同样适用。它能显著提升推理速度特别是在批量处理大量成绩单时效果更加明显。在实际测试中使用vLLM加速后单张成绩单的处理时间从原来的2-3秒缩短到0.5-1秒。对于批量处理来说这个提升非常可观。3.3 Gradio前端让操作变得简单Gradio是一个快速构建机器学习Web界面的工具。对于教务老师来说他们不需要懂代码只需要点击上传按钮选择PDF文件点击提交按钮开始处理查看处理结果和统计信息界面简洁直观学习成本几乎为零。4. 实战部署一步步搭建系统4.1 环境准备与安装首先我们需要准备Python环境。建议使用Python 3.9或更高版本。# 创建虚拟环境 python -m venv ocr_env source ocr_env/bin/activate # Linux/Mac # 或 ocr_env\Scripts\activate # Windows # 安装基础依赖 pip install torch torchvision torchaudio pip install transformers pip install vllm pip install gradio pip install pymupdf # 用于PDF处理 pip install pandas # 用于数据处理 pip install sqlalchemy # 用于数据库操作4.2 下载和加载DeepSeek-OCR-2模型DeepSeek-OCR-2模型可以从Hugging Face下载。由于模型较大建议在有GPU的服务器上运行。from transformers import AutoProcessor, AutoModelForVision2Seq import torch # 加载模型和处理器 model_name deepseek-ai/deepseek-ocr-2 print(正在加载DeepSeek-OCR-2模型...) processor AutoProcessor.from_pretrained(model_name) model AutoModelForVision2Seq.from_pretrained( model_name, torch_dtypetorch.float16 if torch.cuda.is_available() else torch.float32, device_mapauto ) print(模型加载完成)4.3 配置vLLM加速推理为了获得更好的性能我们可以使用vLLM来加速推理from vllm import LLM, SamplingParams # 配置vLLM llm LLM( modeldeepseek-ai/deepseek-ocr-2, tensor_parallel_size1, # 根据GPU数量调整 gpu_memory_utilization0.9, max_model_len4096 ) # 设置生成参数 sampling_params SamplingParams( temperature0.1, top_p0.9, max_tokens1024 )4.4 PDF预处理模块成绩单PDF可能有多种格式我们需要统一处理import fitz # PyMuPDF from PIL import Image import io def pdf_to_images(pdf_path, dpi300): 将PDF转换为图像列表 doc fitz.open(pdf_path) images [] for page_num in range(len(doc)): page doc.load_page(page_num) # 设置DPI提高图像质量 mat fitz.Matrix(dpi/72, dpi/72) pix page.get_pixmap(matrixmat) # 转换为PIL Image img_data pix.tobytes(ppm) img Image.open(io.BytesIO(img_data)) images.append(img) doc.close() return images def preprocess_image(image): 图像预处理调整大小、增强对比度等 # 转换为RGB模式 if image.mode ! RGB: image image.convert(RGB) # 调整大小保持长宽比 max_size 2048 if max(image.size) max_size: ratio max_size / max(image.size) new_size tuple(int(dim * ratio) for dim in image.size) image image.resize(new_size, Image.Resampling.LANCZOS) return image5. 核心识别逻辑从图像到结构化数据5.1 OCR识别函数这是系统的核心部分负责调用DeepSeek-OCR-2进行识别def ocr_recognize(image, processor, model): 使用DeepSeek-OCR-2识别图像中的文字和结构 # 预处理图像 processed_image preprocess_image(image) # 准备输入 inputs processor( imagesprocessed_image, return_tensorspt, paddingTrue ).to(model.device) # 生成识别结果 with torch.no_grad(): generated_ids model.generate( **inputs, max_new_tokens1024, num_beams3, early_stoppingTrue ) # 解码结果 generated_text processor.batch_decode( generated_ids, skip_special_tokensTrue )[0] return generated_text def batch_ocr_recognize(images, llm, sampling_params): 批量OCR识别使用vLLM加速 results [] for image in images: # 将图像转换为base64或保存为临时文件 # 这里简化处理实际使用时需要适配vLLM的输入格式 processed_image preprocess_image(image) # 使用vLLM进行推理 # 注意这里需要根据实际模型输入格式调整 prompt f请识别以下图像中的文字和表格结构 outputs llm.generate([prompt], sampling_params) result outputs[0].outputs[0].text results.append(result) return results5.2 成绩单数据解析识别出来的文本需要进一步解析为结构化数据import re import pandas as pd def parse_transcript_text(ocr_text): 解析OCR识别出的成绩单文本 data { student_info: {}, courses: [], summary: {} } # 提取学生基本信息 student_patterns { name: r姓名[:]\s*([^\n]), student_id: r学号[:]\s*([^\n]), college: r学院[:]\s*([^\n]), major: r专业[:]\s*([^\n]), grade: r年级[:]\s*([^\n]) } for key, pattern in student_patterns.items(): match re.search(pattern, ocr_text) if match: data[student_info][key] match.group(1).strip() # 提取课程成绩表格部分 # 假设成绩单表格有固定格式 course_lines [] lines ocr_text.split(\n) in_course_table False for line in lines: # 检测表格开始 if any(marker in line for marker in [课程名称, 课程代码, 成绩, 学分]): in_course_table True continue if in_course_table: # 跳过空行和表尾 if not line.strip() or any(marker in line for marker in [总计, 平均, GPA]): in_course_table False continue # 解析课程行 # 这里需要根据实际格式调整正则表达式 course_match re.match(r(.?)\s([A-Z0-9])\s([\d.])\s([\d.])\s([A-F\\-]?[\d.]), line) if course_match: course_data { course_name: course_match.group(1).strip(), course_code: course_match.group(2).strip(), credit: float(course_match.group(3)), score: float(course_match.group(4)) if course_match.group(4).replace(., ).isdigit() else course_match.group(4), grade: course_match.group(5).strip() if len(course_match.groups()) 4 else } data[courses].append(course_data) # 提取统计信息 summary_patterns { total_credits: r总学分[:]\s*([\d.]), gpa: r平均绩点[:]\s*([\d.]), weighted_score: r加权平均分[:]\s*([\d.]) } for key, pattern in summary_patterns.items(): match re.search(pattern, ocr_text) if match: data[summary][key] float(match.group(1)) if . in match.group(1) else int(match.group(1)) return data def validate_transcript_data(data): 验证解析出的成绩单数据 errors [] # 检查必填字段 required_fields [name, student_id] for field in required_fields: if field not in data[student_info] or not data[student_info][field]: errors.append(f缺少学生{field}) # 检查课程数据 if not data[courses]: errors.append(未识别到课程信息) else: for i, course in enumerate(data[courses]): if not course.get(course_name): errors.append(f第{i1}门课程缺少课程名称) if not course.get(course_code): errors.append(f第{i1}门课程缺少课程代码) # 检查学分和成绩的合理性 for i, course in enumerate(data[courses]): credit course.get(credit, 0) score course.get(score, 0) if credit 0 or credit 10: errors.append(f第{i1}门课程学分{credit}不合理) if isinstance(score, (int, float)): if score 0 or score 100: errors.append(f第{i1}门课程成绩{score}不合理) return errors6. 数据库设计与数据入库6.1 数据库表结构设计我们需要设计合理的数据库表来存储成绩单数据from sqlalchemy import create_engine, Column, Integer, String, Float, DateTime, Text from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker from datetime import datetime Base declarative_base() class Student(Base): 学生信息表 __tablename__ students id Column(Integer, primary_keyTrue) student_id Column(String(20), uniqueTrue, nullableFalse, indexTrue) name Column(String(50), nullableFalse) college Column(String(100)) major Column(String(100)) grade Column(String(10)) created_at Column(DateTime, defaultdatetime.now) updated_at Column(DateTime, defaultdatetime.now, onupdatedatetime.now) class Course(Base): 课程信息表 __tablename__ courses id Column(Integer, primary_keyTrue) course_code Column(String(20), uniqueTrue, nullableFalse, indexTrue) course_name Column(String(100), nullableFalse) credit Column(Float, nullableFalse) created_at Column(DateTime, defaultdatetime.now) class Transcript(Base): 成绩单表 __tablename__ transcripts id Column(Integer, primary_keyTrue) student_id Column(String(20), nullableFalse, indexTrue) semester Column(String(20), nullableFalse) # 如2023-2024-1 total_credits Column(Float) gpa Column(Float) weighted_score Column(Float) pdf_path Column(String(500)) # 原始PDF文件路径 ocr_raw_text Column(Text) # OCR原始识别文本 processed_data Column(Text) # 处理后的JSON数据 status Column(String(20), defaultpending) # pending, processed, error error_message Column(Text) created_at Column(DateTime, defaultdatetime.now) processed_at Column(DateTime) class CourseGrade(Base): 课程成绩表 __tablename__ course_grades id Column(Integer, primary_keyTrue) transcript_id Column(Integer, nullableFalse, indexTrue) course_code Column(String(20), nullableFalse) score Column(Float) grade Column(String(5)) # A, B, C, D, F等 created_at Column(DateTime, defaultdatetime.now) # 创建数据库连接 def create_database_engine(db_urlsqlite:///transcripts.db): 创建数据库引擎 engine create_engine(db_url) Base.metadata.create_all(engine) return engine6.2 数据入库函数import json from sqlalchemy.orm import Session def save_transcript_to_db(session, student_info, courses, summary, pdf_path, ocr_text): 将解析后的成绩单数据保存到数据库 try: # 1. 保存或更新学生信息 student session.query(Student).filter_by( student_idstudent_info[student_id] ).first() if not student: student Student( student_idstudent_info[student_id], namestudent_info[name], collegestudent_info.get(college), majorstudent_info.get(major), gradestudent_info.get(grade) ) session.add(student) else: # 更新学生信息 student.name student_info[name] student.college student_info.get(college, student.college) student.major student_info.get(major, student.major) student.grade student_info.get(grade, student.grade) session.flush() # 2. 创建成绩单记录 # 从文件名或OCR文本中提取学期信息 semester extract_semester_from_pdf(pdf_path) or 未知学期 transcript Transcript( student_idstudent_info[student_id], semestersemester, total_creditssummary.get(total_credits), gpasummary.get(gpa), weighted_scoresummary.get(weighted_score), pdf_pathpdf_path, ocr_raw_textocr_text, processed_datajson.dumps({ student_info: student_info, courses: courses, summary: summary }, ensure_asciiFalse), statusprocessed, processed_atdatetime.now() ) session.add(transcript) session.flush() # 3. 保存课程成绩 for course in courses: # 先确保课程信息存在 course_record session.query(Course).filter_by( course_codecourse[course_code] ).first() if not course_record: course_record Course( course_codecourse[course_code], course_namecourse[course_name], creditcourse[credit] ) session.add(course_record) # 保存成绩 course_grade CourseGrade( transcript_idtranscript.id, course_codecourse[course_code], scorecourse.get(score), gradecourse.get(grade) ) session.add(course_grade) session.commit() return True, 数据保存成功 except Exception as e: session.rollback() return False, f数据保存失败: {str(e)} def extract_semester_from_pdf(pdf_path): 从PDF文件名或内容中提取学期信息 import os filename os.path.basename(pdf_path) # 尝试从文件名中提取学期信息 # 例如2023012345_2023-2024-1_成绩单.pdf patterns [ r(\d{4}-\d{4}-\d), # 2023-2024-1 r(\d{4}[上下]), # 2023上 r(\d{4}春|\d{4}秋), # 2023春 ] for pattern in patterns: match re.search(pattern, filename) if match: return match.group(1) return None7. Gradio前端界面设计7.1 构建用户友好的Web界面Gradio让我们能够快速构建一个美观实用的前端界面import gradio as gr import os from pathlib import Path def create_gradio_interface(): 创建Gradio Web界面 # 初始化数据库 engine create_database_engine() SessionLocal sessionmaker(bindengine) def process_pdf_files(files, progressgr.Progress()): 处理上传的PDF文件 results [] stats { total: len(files), success: 0, failed: 0, errors: [] } for i, file_info in enumerate(progress.tqdm(files, desc处理PDF文件)): try: file_path file_info.name filename os.path.basename(file_path) # 更新进度 progress((i 1) / len(files), descf正在处理: {filename}) # 1. PDF转图像 images pdf_to_images(file_path) if not images: stats[failed] 1 stats[errors].append(f{filename}: 无法读取PDF文件) results.append({ filename: filename, status: 失败, message: 无法读取PDF文件, details: }) continue # 2. OCR识别 ocr_results [] for img in images: ocr_text ocr_recognize(img, processor, model) ocr_results.append(ocr_text) full_ocr_text \n\n--- 页面分隔 ---\n\n.join(ocr_results) # 3. 解析数据 parsed_data parse_transcript_text(full_ocr_text) # 4. 数据验证 validation_errors validate_transcript_data(parsed_data) if validation_errors: stats[failed] 1 error_msg ; .join(validation_errors) stats[errors].append(f{filename}: {error_msg}) results.append({ filename: filename, status: 失败, message: 数据验证失败, details: error_msg }) continue # 5. 保存到数据库 session SessionLocal() success, message save_transcript_to_db( session, parsed_data[student_info], parsed_data[courses], parsed_data[summary], file_path, full_ocr_text ) session.close() if success: stats[success] 1 student_info parsed_data[student_info] results.append({ filename: filename, status: 成功, message: f学生: {student_info.get(name, 未知)}, details: f学号: {student_info.get(student_id, 未知)}, f课程数: {len(parsed_data[courses])} }) else: stats[failed] 1 stats[errors].append(f{filename}: {message}) results.append({ filename: filename, status: 失败, message: 数据库保存失败, details: message }) except Exception as e: stats[failed] 1 error_msg str(e) stats[errors].append(f{filename}: {error_msg}) results.append({ filename: filename, status: 失败, message: 处理过程中出错, details: error_msg }) # 生成统计信息 summary f ## 处理完成 **统计信息** - 总文件数: {stats[total]} - 成功: {stats[success]} - 失败: {stats[failed]} - 成功率: {stats[success]/stats[total]*100:.1f}% **处理结果** # 生成结果表格 result_table | 文件名 | 状态 | 学生信息 | 详情 |\n result_table |--------|------|----------|------|\n for result in results: status_color if result[status] 成功 else result_table f| {result[filename]} | {status_color} {result[status]} | {result[message]} | {result[details]} |\n if stats[errors]: summary \n**错误列表**\n for error in stats[errors]: summary f- {error}\n return summary \n result_table def query_student_info(student_idNone, nameNone): 查询学生成绩信息 session SessionLocal() try: query session.query(Transcript, Student).join( Student, Transcript.student_id Student.student_id ) if student_id: query query.filter(Transcript.student_id.like(f%{student_id}%)) if name: query query.filter(Student.name.like(f%{name}%)) results query.order_by(Transcript.semester.desc()).limit(20).all() if not results: return 未找到相关学生信息 output ## 查询结果\n\n for transcript, student in results: output f### {student.name} ({student.student_id})\n output f- 学院: {student.college or 未知}\n output f- 专业: {student.major or 未知}\n output f- 学期: {transcript.semester}\n output f- 总学分: {transcript.total_credits or 未知}\n output f- GPA: {transcript.gpa or 未知}\n output f- 处理时间: {transcript.processed_at.strftime(%Y-%m-%d %H:%M:%S)}\n\n # 查询课程成绩 grades session.query(CourseGrade, Course).join( Course, CourseGrade.course_code Course.course_code ).filter(CourseGrade.transcript_id transcript.id).all() if grades: output **课程成绩**\n output | 课程代码 | 课程名称 | 学分 | 成绩 | 等级 |\n output |----------|----------|------|------|------|\n for grade, course in grades: output f| {course.course_code} | {course.course_name} | {course.credit} | {grade.score or 未录入} | {grade.grade or 未录入} |\n output \n output ---\n\n return output finally: session.close() # 创建Gradio界面 with gr.Blocks(title成绩单自动处理系统, themegr.themes.Soft()) as demo: gr.Markdown(# 高校成绩单自动处理系统) gr.Markdown(上传PDF格式的成绩单文件系统将自动识别并存入数据库) with gr.Tabs(): with gr.TabItem( 上传处理): with gr.Row(): with gr.Column(scale2): file_input gr.File( label选择PDF文件, file_countmultiple, file_types[.pdf], typefilepath ) process_btn gr.Button(开始处理, variantprimary) with gr.Accordion(高级选项, openFalse): output_dir gr.Textbox( label输出目录, value./processed, placeholder处理后的文件保存目录 ) dpi_setting gr.Slider( labelPDF转换DPI, minimum150, maximum600, value300, step50 ) with gr.Column(scale3): output_result gr.Markdown(label处理结果) progress_bar gr.Slider( minimum0, maximum100, value0, label处理进度, interactiveFalse ) process_btn.click( fnprocess_pdf_files, inputs[file_input], outputs[output_result] ) with gr.TabItem( 查询成绩): with gr.Row(): with gr.Column(): search_student_id gr.Textbox( label学号, placeholder输入学号支持模糊查询 ) search_name gr.Textbox( label姓名, placeholder输入姓名支持模糊查询 ) search_btn gr.Button(查询, variantprimary) with gr.Column(): search_result gr.Markdown(label查询结果) search_btn.click( fnquery_student_info, inputs[search_student_id, search_name], outputs[search_result] ) with gr.TabItem( 数据统计): def show_statistics(): session SessionLocal() try: # 统计学生数量 student_count session.query(Student).count() # 统计成绩单数量 transcript_count session.query(Transcript).count() # 统计课程数量 course_count session.query(Course).count() # 统计各学期成绩单数量 semester_stats session.query( Transcript.semester, gr.func.count(Transcript.id).label(count) ).group_by(Transcript.semester).all() stats_text f ## 数据统计概览 **基本信息** - 学生总数: {student_count} 人 - 成绩单总数: {transcript_count} 份 - 课程总数: {course_count} 门 **各学期成绩单数量** for semester, count in semester_stats: stats_text f- {semester or 未知学期}: {count} 份\n return stats_text finally: session.close() stats_display gr.Markdown(label统计信息) refresh_btn gr.Button(刷新统计, variantsecondary) refresh_btn.click( fnshow_statistics, inputs[], outputs[stats_display] ) demo.load(show_statistics, inputs[], outputs[stats_display]) gr.Markdown(---) gr.Markdown(### 使用说明) gr.Markdown( 1. **上传处理**选择PDF格式的成绩单文件点击开始处理按钮 2. **查询成绩**通过学号或姓名查询学生成绩信息 3. **数据统计**查看系统处理数据的统计信息 **支持功能** - 批量上传和处理PDF成绩单 - 自动识别学生信息、课程成绩 - 数据验证和错误提示 - 数据库存储和查询 - 处理进度实时显示 ) return demo7.2 启动Web服务def main(): 主函数启动Gradio Web服务 print(正在初始化系统...) # 初始化模型在实际使用中这里需要加载模型 # processor, model initialize_models() # 创建Gradio界面 demo create_gradio_interface() # 启动服务 print(系统初始化完成) print(正在启动Web服务...) print(请在浏览器中访问: http://localhost:7860) demo.launch( server_name0.0.0.0, server_port7860, shareFalse, # 设置为True可生成公共链接 debugFalse ) if __name__ __main__: main()8. 系统优化与扩展8.1 性能优化建议在实际使用中你可能需要对系统进行一些优化# 1. 批量处理优化 def batch_process_pdfs(pdf_files, batch_size10): 批量处理PDF文件提高效率 results [] for i in range(0, len(pdf_files), batch_size): batch pdf_files[i:ibatch_size] # 使用多线程或异步处理 batch_results process_batch_async(batch) results.extend(batch_results) return results # 2. 缓存机制 import hashlib from functools import lru_cache lru_cache(maxsize100) def get_cached_ocr_result(image_hash): 缓存OCR结果避免重复处理相同图像 pass # 3. 错误重试机制 def process_with_retry(file_path, max_retries3): 带重试机制的文件处理 for attempt in range(max_retries): try: return process_single_file(file_path) except Exception as e: if attempt max_retries - 1: raise print(f第{attempt1}次尝试失败正在重试...) time.sleep(2 ** attempt) # 指数退避8.2 功能扩展建议系统可以进一步扩展以下功能模板匹配针对不同学校的不同成绩单格式建立模板库质量检测自动检测PDF质量提示用户重新扫描模糊文件批量导出支持将数据导出为Excel、CSV等格式权限管理添加用户登录和权限控制API接口提供RESTful API供其他系统调用数据可视化生成成绩分布图、趋势分析等9. 总结通过这个实战项目我们构建了一个完整的高校成绩单PDF自动处理系统。系统核心基于DeepSeek-OCR-2的智能文档识别能力结合vLLM的推理加速和Gradio的友好界面实现了从PDF上传到数据库入库的全自动化流程。9.1 关键收获DeepSeek-OCR-2的强大能力相比传统OCR它能够理解文档结构特别适合处理表格复杂的成绩单vLLM的加速效果在大批量处理时推理速度提升明显Gradio的便捷性快速构建可用的Web界面降低使用门槛完整的工程实践从数据处理到数据库设计再到前端展示覆盖了完整的开发流程9.2 实际应用价值对于高校教务处来说这个系统能够大幅提升效率从人工录入的几分钟每份提升到自动处理的几秒钟每份减少错误率避免人工录入的笔误和遗漏数据标准化统一存储格式便于后续分析和使用历史数据数字化快速将纸质成绩单历史档案数字化9.3 下一步建议如果你想要部署或扩展这个系统我建议先从小规模开始选择一个小型院系进行试点收集反馈并优化建立模板库针对不同格式的成绩单建立识别模板添加人工复核对于识别置信度低的项目提供人工复核界面性能监控添加日志和监控了解系统运行状况定期更新模型关注DeepSeek-OCR模型的更新及时升级以获得更好的识别效果这个系统不仅适用于成绩单处理稍作修改就可以用于其他文档的自动化处理如财务报表、医疗记录、法律文书等。希望这个实战案例能给你带来启发帮助你在实际工作中解决文档处理的难题。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2438768.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…