File size: 5,207 Bytes
b2c2b10 0932db4 b2c2b10 6cf0632 b2c2b10 e23044e b2c2b10 6cf0632 0932db4 e4655c8 0932db4 b2c2b10 0932db4 e23044e 0932db4 5425d90 e76890b 477daa4 0932db4 6cf0632 0932db4 b2c2b10 0932db4 b393081 0932db4 b2c2b10 0932db4 c00c3f0 e76890b 897ecbc 87209c8 b2c2b10 89f7900 f06a433 89f7900 0932db4 6cf0632 e23044e 0932db4 b2c2b10 6cf0632 e23044e ce12e8f b2c2b10 87209c8 b2c2b10 cfca8e6 b2c2b10 eb6129a b2c2b10 b393081 9c8df4d b2c2b10 534e71b c00c3f0 9c8df4d b2c2b10 | 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 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | from transformers import pipeline
import torch
import gradio as gr
import os
from PIL import Image
import pytesseract
import tempfile
import shutil
from pdf2image import convert_from_path
import json
import spaces
model_name = "deepset/roberta-base-squad2"
# Vision QnA requires: PyTesseract for OCR. Tesseract executable needs to be installed separately.
# sudo apt install tesseract-ocr (https://tesseract-ocr.github.io/tessdoc/Installation.html)
vision_qna = pipeline("document-question-answering", model="impira/layoutlm-document-qa", device=0)
def load_file(file_input, encoding = 'utf-8'):
if not os.path.exists(file_input):
raise FileNotFoundError(f"The file does not exist.")
with open(file_input, 'r', encoding=encoding) as file:
try:
content = file.read()
except UnicodeDecodeError:
# If a UnicodeDecodeError occurs, try reading with 'latin1' encoding
with open(file_input, 'r', encoding='latin1') as file:
content = file.read()
return content
def save_image(file):
try:
temp_dir = tempfile.mkdtemp()
file_path = os.path.join(temp_dir, os.path.basename(file.name))
# Copy the file from the temporary Gradio directory to our temporary directory
shutil.copyfile(file.name, file_path)
# when working with saving image files through Gradio,
# using `shutil.copyfile` to handle `NamedString` objects for file uploads is the correct approach
return file_path
except Exception as e:
print(e)
def save_pdf(file):
temp_dir = tempfile.mkdtemp()
pdf_path = os.path.join(temp_dir, os.path.basename(file.name))
# Copy the file from the temporary Gradio directory to our temporary directory
shutil.copyfile(file.name, pdf_path)
# Convert PDF to images
images = convert_from_path(pdf_path)
image_paths = []
for i, img in enumerate(images):
image_path = os.path.join(temp_dir, f'page_{i}.png')
img.save(image_path, 'PNG')
image_paths.append(image_path)
# print(image_paths)
return image_paths
def qna_image_content(content, question):
result = vision_qna(content, question)
page_result = get_page_result(result, question)
return get_result_json([page_result])
def get_page_result(raw_result, question):
# print(raw_result[0]['answer'], raw_result[0]['score'])
page_result = {
"result": {
"question": question,
"answer": raw_result[0]['answer']
},
"confidence": raw_result[0]['score']
}
return page_result
def get_result_json(page_results):
result = {
"pages": page_results
}
return json.dumps(result)
def qna_pdf_content(image_paths, question, short_circuit_threshold):
all_page_results = []
try:
for image_path in image_paths:
result = vision_qna(image=image_path, question=question)
page_result = get_page_result(result, question)
all_page_results.append(page_result)
if result[0]['score'] >= short_circuit_threshold:
break
return get_result_json(all_page_results)
except Exception as e:
return f"An error occurred during processing: {e}"
@spaces.GPU
def predict(doc, question, short_circuit_threshold):
file_input = doc
if file_input is not None and question is not None:
print(f"File type: {type(file_input)}")
print(f"File name: {file_input.name}")
filename_lower = file_input.name.lower()
is_pdf = filename_lower.endswith('.pdf') or filename_lower.endswith("blob")
if is_pdf:
try:
image_paths = save_pdf(file_input)
if not question:
return "Please provide a question."
result = qna_pdf_content(image_paths, question, short_circuit_threshold)
# print(result)
return result
except Exception as e:
return f"An error occurred during vision processing: {e}"
else:
try:
img_file_path = save_image(file_input)
if not question:
return "Please provide a question."
result = qna_image_content(img_file_path, question)
# print(result)
return result
except Exception as e:
return f"An error occurred during vision processing: {e}"
else:
raise gr.Error("Provide both a document and a question")
gr.close_all()
with gr.Blocks() as demo:
gr.Markdown("# LayoutLM Document QnA")
gr.Markdown("This app performs visual document QnA for docs in PDF or image formats.")
file_input = gr.File(label="File Upload", file_types=['png', 'jpeg', 'jpg', 'bmp', 'gif', 'pdf'])
question = gr.Textbox(label="Question", placeholder="Enter your question here...")
threshold_input = gr.Number(label="Short-circuit threshold", value=0.97, minimum=0, maximum=1)
output = gr.JSON(label="Answer")
button = gr.Button("Run model")
button.click(predict, inputs=[file_input, question, threshold_input],
outputs=output)
demo.launch()
# print(qna_image_content("https://gradientflow.com/wp-content/uploads/2023/10/newsletter87-RAG-simple.png", "What is the step prior to embedding?")) |