Strona główna / Artykuły

Od zeskanowanych raportów laboratoryjnych do strukturyzowanych danych: kompromisy w architekturze OCR

Jak startup medyczny z ograniczonym budżetem może ocenić biblioteki OCR, usługi API Google Cloud oraz samodzielnie hostowany model językowy do analizy obrazów, przy przekształcaniu skanów medycznych w ustrukturyzowany JSON.

Wydawca: REACTAPP.TOP8 min czytania1779 słów

Źródła: How We Chose Our OCR Architecture for a Medical Reports Pipeline (Part 1 of 2)

Zmiana zdjęcia wydruku z laboratorium na wiersz zawierający tekst „Hemoglobina, 13,2, g/dL, referencyjne wartości 12,0–15,5” brzmi jak problem OCR, ale rozpoznawanie zwykłego tekstu to dopiero pierwszy krok. Prawdziwe wyzwanie polega na tanim, niezawodnym pozyskiwaniu znaczenia z nieuporządkowanego skanu, bez ujawniania danych pacjenta. Ten przewodnik przedstawia decyzje architektoniczne leżące u podstaw takiego procesu wydobywania informacji dla MVP raportów medycznych, abyś mógł ponownie wykorzystać te rozważania w sytuacjach, gdy napotkasz podobny problem zrozumienia dokumentów przy ograniczonym budżecie.

Wymóg, który kieruje wszystkim

Załóżmy produkt zdrowotny w wczesnej fazie rozwoju. Pacjenci przesyłają zeskanowany raport medyczny – albo plik PDF, albo zdjęcie z telefonu przedstawiające wydrukowaną kartę laboratoryjną. System musi przekształcić go w ustrukturyzowane zapisy zdrowotne, które zarówno pacjent, jak i jego lekarz mogą przeglądać, a które później mogą być wykorzystane do analizy przeprowadzanej przy użyciu sztucznej inteligencji. Każdy zapis wymaga czterech elementów: nazwy parametru, jego zmierzonej wartości, jednostki miary oraz zakresu referencyjnego.

To ostatnie zdanie stanowi sedno sprawy. Narzędzie, które zwraca blok rozpoznanych znaków, samo w sobie nie spełnia tego wymogu. Nadal konieczne jest ustalenie, który numer należy do którego badania, która sekwencja znaków jest jednostką miary oraz który parzysty numerów stanowi normalny zakres. Każda decyzja dotyczy miejsca, w którym odbywa się ten krok „rozumienia”, oraz jego kosztu.

Ograniczenia były typowe dla MVP: mały zespół, niewielki budżet na infrastrukturę oraz przewidywana początkowa liczba plików wynosząca około 500 przesłanych raportów dziennie, co daje w przybliżeniu 30 000 stron miesięcznie.

Decyzja 1: Wybór języka do realizacji

Zalety ekosystemu Pythona są rzeczywiste

Jeśli zaczniemy od pytania „który język oferuje najlepsze narzędzia do OCR i sztucznej inteligencji”, Python bez większych wątpliwości wygrywa. Dojrzałe silniki o otwartym kodzie źródłowym, takie jak PaddleOCR i EasyOCR, są opracowane przede wszystkim dla Pythona, OpenCV ma tam pierwszorzędne interfejsy, a większość przykładów z dziedziny widzenia komputerowego zakłada jego użycie. Pipeline do OCR budowany od zera naturalnie powinien być realizowany w Pythonie.

Warto również być szczerym co do tego, co nie stanowi czynnika wyróżniającego. Google Vision API była jedną z rozważanych opcji płatnych, a Google udostępnia biblioteki klienta dla Pythona oraz Go. Dlatego dostępność SDK nie faworyzowała żadnego z tych języków.

Dlaczego mimo wszystko zwyciężyło Go

Czynniki decydujące dotyczyły otaczającego systemu, a nie samego OCR. Reszta asynchronicznego procesu była już zaplanowana jako zadanie w Go: konsumuje zadań z Redis Streams, pobiera przesłane pliki z chmurnego magazynu Cloudflare R2 i zapisuje wyniki do Postgres. Napisanie kroku ekstrakcji w Pythonie oznaczałoby uruchamianie dwóch środowisk roboczych, z oddzielnym wdrażaniem, zarządzaniem zależnościami i monitorowaniem, dla jednej funkcji. Inżynier realizujący ten projekt był również najbardziej produktywny przy użyciu Go w przypadku tego typu usług infrastrukturalnych.

Ogólna lekcja: język z najobszerniejszym katalogiem bibliotek nie jest automatycznie tym właściwym. Jeśli krok wyodrębniania danych można sprowadzić do wywołania modelu przez HTTP (co ostatecznie ma miejsce w tym projekcie), utrzymanie jednego środowiska wykonawczego dla całej warstwy roboczej często jest bardziej wartościowe niż głębia biblioteki, której prawie nie będziesz korzystać.

Decyzja 2: API chmurowe kontra samodzielne hostowanie – koszty

Zespół porównał cztery opcje w kontekście oczekiwanego obciążenia 30 000 stron miesięcznie. Podane poniżej wartości to szacunki z czasu oceny; ceny w chmurze się zmieniają, więc przed ich wykorzystaniem sprawdź aktualne listy cen.

  • Google Cloud Vision z funkcją DOCUMENT_TEXT_DETECTION. Zwraca surowy tekst wraz z współrzędnymi, bez żadnych ustrukturyzowanych pól. Kosztuje około 1,50 dolara za 1 000 stron, co daje w przybliżeniu 45 dolarów miesięcznie.
  • Google Document AI (Form lub Custom Parser). Zwraca ustrukturyzowane pary klucz-wartość oraz tabele. Za 30–65 dolarów za 1 000 stron, kosztuje to mniej więcej 900–1 950 dolarów miesięcznie.
  • Gemini Flash w Vertex AI. Multimodalny i sterowany promptami, zwraca ustrukturyzowane dane w formacie JSON. Cena ustalana jest według liczby tokenów; szacunkowo wynosi to 20–50 dolarów miesięcznie.
  • Samodzielnie hostowany model językowy do przetwarzania obrazów (MiniCPM-V dostarczany przez Ollama). Bezpośrednio generuje ustrukturyzowane dane w formacie JSON. Koszt to stała rachunek za serwer, wynoszący mniej więcej 40–80 dolarów miesięcznie za VPS, niezależnie od ilości przetwarzanych danych.
  • Prawidłowe interpretowanie liczb

    API Vision wydaje się tania, ale rozwiązuje inne problemy. Informuje ona o tym, że znaki „13.2” pojawiają się w określonych współrzędnych; nie ma pojęcia, że są to wartości hemoglobiny. Nadal musiałbyś sam stworzyć całą warstwę analizy, więc jej cena nie może być porównywana z opcjami zwracającymi dane strukturalne.

    Document AI rzeczywiście zwraca dane w formie strukturalnej, ale koszt około 1000–2000 dolarów miesięcznie to duży koszt zmienny dla produktu, który jeszcze nie przyniósł żadnych dochodów.

    Gemini Flash to naprawdę interesujący kandydat. Cena oparta na tokenach za zeskanowane strony mieści się w tym samym przedziale co rozwiązania typu self-hosting, a unikasz konieczności utrzymywania infrastruktury GPU. Dlaczego więc nie wybrać go?

    Dlaczego self-hosting nadal okazał się lepszy

    Trzy argumenty przesądziły o decyzji:

    • Górna granica kosztów. Specjalny węzeł kosztuje tyle samo, niezależnie od tego, czy przetwarza 5 000, czy 50 000 stron. API oparte na pomiarze nie ma takiej górnej granicy: nagły wzrost ruchu, seria ponownych prób lub masowy import odzwierciedla się bezpośrednio na fakturze.
    • Izolacja danych. Raporty medyczne zawierają chronione informacje zdrowotne. Przeprowadzanie ekstrakcji wewnątrz prywatnej sieci zespołu oznacza, że dokumenty pacjentów nigdy nie są wysyłane do API firmy trzeciej przy każdym przesyłaniu, co unika całej serii kwestii związanych z przestrzeganiem regulacji i oceną dostawców, z którymi zespół MVP ma niewiele możliwości radzenia sobie.
    • Brak zewnętrznych kwot lub opóźnień. Nie ma ograniczeń szybkości, poziomów równoczesności ani dodatkowych przeskoków sieciowych na kluczowej ścieżce.

    W rezultacie odrzucono opcje Google Cloud i Vertex AI, decydując się na całkowicie samodzielnie hostowany stack.

    Pomaga też spojrzeć na drugą stronę medalu. Stała rachunek za serwer jest przewidywalny tylko do poziomu przepustowości, jaką może obsłużyć dany sprzęt; po tym punkcie musisz sam kupować dodatkowy hardware oraz zajmować się planowaniem mocy obliczeniowej i czasem dostępności. Samodzielne hostowanie również nie eliminuje obowiązków związanych z przestrzeganiem regulacji, ponieważ nadal jesteś odpowiedzialny za przechowywanie danych, kontrolę dostępu oraz ich audyt. W przypadku małej, stałej ilości pracy z wrażliwymi danymi, samodzielne hostowanie zazwyczaj jest korzystniejsze; natomiast przy gwałtownym wzroście obciążenia i braku zespołu zajmującego się operacjami, lepszym rozwiązaniem może być zarządzana API.

    Decyzja 3: Pominięcie tradycyjnych bibliotek OCR

    Silniki otwartego oprogramowania takie jak PaddleOCR i Docling są zdolne do tego, ale ich wyniki są przeznaczone do wyświetlania. Zazwyczaj otrzymuje się treść umieszczoną w tagach układu lub sformatowaną jako Markdown, aby dobrze wyglądała w interfejsie użytkownika lub widoku HTML. Jest to idealne, gdy ktoś ma przeczytać wynik, ale niepraktyczne, gdy kod musi wydobyć „Hemoglobina: 13,2 g/dL” jako czyste pole danych.

    Zamknięcie tej luki to projekt sam w sobie. Trzeba by wydobywać wartości z struktury tagów, przechodzić przez wiele prób i błędów, aby poradzić sobie z różnymi układami raportów w poszczególnych laboratoriach, a prawdopodobnie dodatkowo zastosować preprocesing lub postprocesing za pomocą OpenCV w przypadku tabel i obszarów, które silnik nie przetworzył poprawnie. Wszystko to dodatkowo obciąża pracę związana już z integracją i hostowaniem silnika OCR. Dla wersji MVP oznacza to ogromny zakres prac inżynieryjnych przy czym chodzi tu o infrastrukturę, a nie o sam produkt.

    Należy podkreślić jedną ważną uwagę: ta ocena odzwierciedla ocenę zespołu, a nie ostateczną decyzję dotyczącą tych narzędzi. Inżynierowie z większym doświadczeniem w PaddleOCR lub Docling mogą znać szybsze sposoby przekształcania ich strukturyzowanych wyników w czyste dane, a oba projekty rozwijają się szybko, więc warto ponownie sprawdzić ich obecne formaty wyjściowe.

    Decyzja 4: Samodzielnie hostowany model językowy do rozpoznawania obrazu, dostosowany do budżetu

    Wyodrębnianie znaczenia zamiast znaków

    Opcją zamiast „OCR, a następnie napisanie parsera dla wyników OCR” jest zlecenie modelowi językowemu zdolnemu do rozpoznawania obrazu wykonania obu kroków jednocześnie. Klasyczny OCR rozpoznaje znaki. Model językowy do rozpoznawania obrazu, otrzymawszy dobrze skonstruowany prompt, może przeanalizować zeskanowaną stronę i bezpośrednio zwrócić pola parametru, wartości oraz jednostki, pomijając pośredni krok przetwarzania zaznaczonych danych w formacie Markdown.

    Tutaj umiejętność rozpoznawania obrazu jest niezbędna, a nie opcjonalnym ulepszeniem. Model zawierający tylko tekst nie może pomóc przy zeskanowanym obrazie, ponieważ jeszcze nie ma w nim tekstu. Model musi sam odczytać piksele.

    Taki podejście niesie ze sobą określone ryzyka, dlatego warto planować je od samego początku. Modele językowe mogą błędnie odczytać cyfry lub wygenerować wartości pozornie prawdopodobne, które w rzeczywistości nie występują na stronie, a szczególnie mniejsze modele nie zawsze zwracają dokładnie taką strukturę JSON, o którą prosimy. W przypadku danych zdrowotnych konieczne jest obronne analizowanie odpowiedzi modelu, weryfikacja wartości pod kątem oczekiwanych typów i zakresów oraz możliwość dla użytkowników lub klinicystów sprawdzenia i skorygowania oryginalnego dokumentu.

    Wybór modelu, który faktycznie można uruchomić

    Wybór modelu opierał się na tej samej logice budżetowej. Większe modele Qwen zdolne do obsługi obrazów są skuteczne, ale uruchomienie takiego modelu w tej klasie wielkości wymaga większej ilości pamięci VRAM i mocy obliczeniowej, niż było to uzasadnione dla infrastruktury, za którą zespół płacił z budżetu MVP. Ostatecznie wybrano MiniCPM-V: znacznie mniejszy model, który Ollama może uruchamiać na tani sprzęt bez żadnych problemów, a jednocześnie wystarczająco dobry do strukturalnego wydobywania informacji z obrazów raportów laboratoryjnych.

    Jeśli powtórzysz to ćwiczenie, przetestuj kandydujące modele na reprezentatywnym zbiorze twoich rzeczywistych dokumentów, w tym na rozmytych zdjęciach z telefonu i nietypowych układach laboratoriów, zamiast polegać wyłącznie na wynikach z listy liderów. Najlepszy model teoretycznie nie ma znaczenia, jeśli nie stać cię na jego uruchomienie.

    Czego jeszcze potrzebuje implementacja

    Opisana powyżej architektura określa co ma być przetwarzane; pipeline produkcyjny musi nadal rozwiązać problem jak to zrobić. Dalsze prace obejmują konwersję plików PDF na obrazy, które model może odczytać, strukturyzację żądania i promptu do API Ollama, ostrożne parsowanie JSON w przypadku, gdy mały model odbiega od wymaganego formatu, oraz wykorzystanie Redis Streams w procesorze Go, aby raporty były przetwarzane niezawodnie wraz ze wzrostem objętości danych.

    Główne wnioski

    • Najpierw zdefiniuj wymagany wynik (tutaj: nazwa, wartość, jednostka, zakres odniesienia), zanim porównasz narzędzia; surowy tekst OCR i dane strukturyzowane to różne produkty o różnych cenach.
    • Wybierz język procesora dla całego systemu, a nie tylko ten, który oferuje najbogatszą bibliotekę dla jednego komponentu.
    • Porównuj opcje chmurowe pod kątem równoważnego wyniku, a następnie rozważ ograniczenia kosztowe, izolację danych i kwoty obok ceny bazowej.
  • Wyniki OCR skoncentrowane na renderowaniu mogą ukrywać złożony proces analizy tekstu; model językowy do przetwarzania obrazu może połączyć funkcje OCR i analizy w jednym kroku.
  • Dostosuj rozmiar modelu do sprzętu, za który możesz zapłacić, rygorystycznie weryfikuj jego wyniki oraz ponownie sprawdź ceny i możliwości narzędzia przed podjęciem decyzji.