রেন্ডার টাইমে PDF পার্স করা বন্ধ করুন

বেশিরভাগ ডেভেলপাররা ভুল পদ্ধতিতে PDF এক্সট্রাকশন টুল তৈরি করেন।

তারা ভিজ্যুয়াল আউটপুট থেকে ডকুমেন্টের গঠন অনুমান করার চেষ্টা করেন। তারা একটি পেজকে ক্যানভাসে রেন্ডার করেন এবং পিক্সেল পজিশনগুলো দেখেন। তারা কলাম বা টেবিল খুঁজে পেতে কম্পিউটার ভিশন ব্যবহার করেন।

এই পদ্ধতিটি উল্টো।

একটি PDF-এর অপারেটর স্ট্রিমেই (operator stream) আপনার প্রয়োজনীয় গঠনটি আগে থেকেই বিদ্যমান থাকে।

একটি টেবিল কেবল পিক্সেলের সমষ্টি নয়। এটি moveTo, lineTo এবং rectangle-এর মতো পাথ অপারেটরগুলোর (path operators) একটি সেট। জোনের সীমানা CTM স্ট্যাকে এনকোড করা থাকে। যা ইতিমধ্যে সেখানে আছে তা পুনরায় তৈরি করার প্রয়োজন নেই।

ভিজ্যুয়াল হিউরিস্টিকস (visual heuristics) ব্যবহার করা বন্ধ করুন। সোর্স ডেটা ব্যবহার করুন।

আমি আগে বাউন্ডিং বক্সের (bounding boxes) জন্য De Casteljau subdivision ব্যবহার করার চেষ্টা করেছিলাম। পরীক্ষার সময় আমি এটি বাতিল করে দিয়েছি।

De Casteljau হলো একটি সাবডিভিশন অ্যালগরিদম। আপনি কার্ভগুলোকে ততক্ষণ বিভক্ত করেন যতক্ষণ না সেগমেন্টগুলো যথেষ্ট ছোট হয়। এটি রেন্ডারিংয়ের জন্য কার্যকর, কিন্তু বাউন্ডিং বক্সের জন্য এটি খারাপ।

আপনাকে একটি টলারেন্স (tolerance) বেছে নিতে হবে। যদি টলারেন্স খুব বেশি ঢিলেঢালা হয়, তবে বক্সটি ভুল হবে। আর যদি খুব টাইট হয়, তবে রিকার্সনে (recursion) আপনি রিসোর্স নষ্ট করবেন। এর চেয়ে ভালো একটি উপায় আছে। কোয়াড্রাটিক ফর্মুলা (quadratic formula) ব্যবহার করে একটি অ্যানালিটিক্যাল সমাধান একদম নির্ভুল। এটি রিকার্সন করে না এবং কোনো সেগমেন্ট বরাদ্দও করে না।

একই যুক্তি জোন শনাক্তকরণের ক্ষেত্রেও প্রযোজ্য।

অনেক টুল দুটি টেক্সট গ্রুপের মধ্যবর্তী বিন্দু (midpoint) খুঁজে বের করার মাধ্যমে জোনের সীমানা গণনা করে। এটি একটি ভিজ্যুয়াল অনুমান মাত্র। এটি কাঠামোগত নয়।

আপনি যদি মিডপয়েন্ট ব্যবহার করেন, তবে সাব-পিক্সেল রাউন্ডিং (sub-pixel rounding) অঞ্চলগুলোকে ভুল জোনে নিয়ে যাবে।

সমাধানটি সহজ। বাউন্ডিং বক্সের উপরের প্রান্ত (top edge) ব্যবহার করুন। একটি অঞ্চল কোথায় শুরু হচ্ছে তার ওপর ভিত্তি করে সেটি একটি জোনের অন্তর্ভুক্ত হয়। উপরের প্রান্তের প্রকৃত Y-কোঅর্ডিনেট (Y-coordinate) ব্যবহার করুন।

একটি প্রকৃত PDF এক্সট্রাক্টর তৈরি করা আরও কঠিন। আপনাকে অবশ্যই:

এটি পিক্সেল-ভিত্তিক অনুমানের চেয়ে অনেক বেশি কাজ। কিন্তু এটি ডিটারমিনিস্টিক (deterministic) ফলাফল প্রদান করে।

একটি পিক্সেল-ভিত্তিক টুল ১০০% জুম এবং ১৫০% জুমের ক্ষেত্রে ভিন্ন ভিন্ন ফলাফল দেয়। এটি ভিজ্যুয়াল আর্টিফ্যাক্টগুলোর প্যাটার্ন ম্যাচিং করে, কাঠামো এক্সট্রাক্ট করে না।

আপনি যদি অপারেটর স্ট্রিম পার্স না করেন, তবে আপনি কেবল একটি ডেমো তৈরি করছেন। এটি আপনার টেস্ট ফাইলগুলোতে কাজ করতে পারে, কিন্তু আসল ব্যবহারকারীর আপলোড করা ফাইলগুলোতে এটি ব্যর্থ হবে।

অপারেটর স্ট্রিমের মাধ্যমে কাজ করা কঠিন। আপনাকে fill এবং stroke স্টেট মেশিন এবং PDF স্পেসিফিকেশন বুঝতে হবে। কিন্তু আপনাকে এটি কেবল একবারই শিখতে হবে। তারপর এটি প্রতিটি PDF-এর জন্য কাজ করবে।

রেন্ডার-টাইমে PDF পার্স করা বন্ধ করুন: স্ট্রাকচার্ড এক্সট্রাকশনের জন্য একটি উন্নত আর্কিটেকচার

আপনি যদি PDF থেকে ডেটা এক্সট্রাক্ট করার জন্য একটি LLM-চালিত অ্যাপ্লিকেশন তৈরি করেন, তবে আপনি হয়তো ভুল পদ্ধতিতে এটি করছেন।

বেশিরভাগ ডেভেলপার এমন একটি প্যাটার্ন অনুসরণ করেন যেখানে ব্যবহারকারী যখন ডেটা বা উত্তর চান, তখনই কেবল PDF পার্স করা হয়। একে বলা হয় "রেন্ডার-টাইম" (render-time) পার্সিং।

এই পদ্ধতির তিনটি প্রধান ত্রুটি রয়েছে:

  1. ল্যাটেন্সি (Latency): একটি জটিল PDF পার্স করতে বেশ কিছুটা সময় লাগে, যা ব্যবহারকারীর অভিজ্ঞতাকে ধীর করে দেয়।
  2. খরচ (Cost): প্রতিবার ব্যবহারকারী প্রশ্ন করার সময় ডেটা স্ট্রাকচার করার জন্য LLM কল করা অত্যন্ত ব্যয়বহুল।
  3. নির্ভরযোগ্যতা (Reliability): PDF পার্সিং অত্যন্ত জটিল একটি কাজ। রেন্ডার-টাইমে এটি করার ফলে সিস্টেমের ব্যর্থতার সম্ভাবনা বেড়ে যায়।

সমাধান: ইনজেশন-টাইম (Ingestion-time) পার্সিং

কুয়েরি-টাইমে পার্স করার পরিবর্তে, ডকুমেন্টটি যখন প্রথম আপনার সিস্টেমে ইনজেস্ট (ingest) করা হয়, তখনই সেটি পার্স করে ফেলুন।

কাজের ধারাটি (workflow) এমন হওয়া উচিত:

  1. ইনজেশন (Ingestion): ব্যবহারকারী একটি PDF আপলোড করেন।
  2. পার্সিং এবং লেআউট অ্যানালাইসিস (Parsing & Layout Analysis): টেবিল, হেডার এবং টেক্সট ব্লক শনাক্ত করতে একটি টুল ব্যবহার করুন।
  3. স্ট্রাকচার্ড এক্সট্রাকশন (Structured Extraction): পার্স করা লেআউটটিকে একটি পরিচ্ছন্ন JSON অবজেক্টে রূপান্তর করতে একটি LLM ব্যবহার করুন।
  4. স্টোরেজ (Storage): এই JSON-টি একটি ডাটাবেসে (যেমন: PostgreSQL-এর JSONB ফরম্যাটে) সংরক্ষণ করুন।
  5. রিট্রিভাল (Retrieval): যখন একজন ব্যবহারকারী প্রশ্ন করবেন, তখন সরাসরি ডাটাবেস থেকে JSON কুয়েরি করুন।

কেন এটি উন্নত

ভারী কাজগুলো ইনজেশন ফেজে নিয়ে আসার মাধ্যমে আপনি যা অর্জন করবেন: