Найяскравіший.OcrNer M SK1 Пакет NuGet ( Частка МSK3 (Українська (Ukrainian))

Найяскравіший.OcrNer M SK1 Пакет NuGet ( Частка МSK3

Thursday, 12 February 2026

//

21 minute read

В Частина 1 Я показав сирову трубу. МСК0. Ручно завантажуючи моделі. МSK1. Пишаючи токенізер. ММК2. Використовуючи набір ONNX. МКС3. І розшифровуючи BIO-теги вручну. ММСК4. Освітній. МПСК5. Але багато водопроводів, щоб зробити все правильно. МУСК6.

Тепер це - пакет NuGet Один ряд установок, нуль загрузок моделей - все автоматизовано -завантаження на перший разM SK2

Nota: Цей пакет є спрощеним, фокусованим інструментом для видобутку тексту та об 'єктів з зображень будь-що (фотографіїM SK1 документи МSK2 скриншоти , ручний малюнокМSK4 анімованіGIFи і навіть відео) з неяскравим співпадіннямMSC6 консенсус OCRMST7 та структурований видобутокМST8 перевірте прозораРАГ де проходить виробництво-швидкісної версії цього трубопроводуM SK1


Короткий словник (Якщо виM SK1Новый до цього)

Перед тим, як зануритися в це слово:

  • ОCR (Опtical Character RecognitionM SK1 - Перетворення зображення тексту в реальні текстові символи, з яким може працювати ваш код. Подумайте
  • NER (Назвизнання іменних об 'єктівM SK1 - сканування тексту, щоб знайти та класифікувати імена речей. " Джон Сміт працює в Microsoft у СіетліMSC5 стаєMSSK6 ДжонСміт МSK7 ЛюдинаMSL8 Microsoft МSK9 ОрганізаціяMСК10 Сіетл ♫ = Местонахождение ♫ МСК12 ♫
  • Пропускний час на NX - спосіб запускати моделі машинного навчання так само як модель BERT, яку ми використовуємо для NER .onnx файл, локально
  • БЕРТ - це попереднє МSK1 тренований модель мови від Google, яка розуміє контекст у тексті . Варіант NER був добре влаштований CoNLL-2003 набір даних для розпізнавання людей, організаційM SK1 локаційМSK2 та різних груп.
  • Флоренція-2 - маленька модель візуалізації від Microsoft, яка може описати бачить в зображенні (капції , об 'єкти, текстM SK3 По-іншому, ніж Тесеракт, він розуміє всю сценуMSC4 не лише символиMST5

Чому більше ніж простий тексеракт

Tesseract ефективний для чистого тексту dokumentu, але він потрапив на шумні фотографіїМSK1 низькийM SK2 контрастні скани, і змішені MSC4 сцена МСК5 текстМ СК6 зображенняMСК7 Він також зупиняється на сирому тексті МСК8 ви все ще потребуєте додаткового коду, щоб перетворити цей текст на структуровані об 'єкти, які ви дійсно можете використовуватиMSК9

Цей пакет вирішує ці прогалини.

  1. Зображення передрозробка - сірий діапазон , покращення контрасту МSK2 приголомшування під OCR МSK3 обоє Tesseract і Florence
  2. Флоренція-2 візуалізація - локальне субтитриювання зображення і OCR через ONNX (без хмарного API МSK2
  3. BERT NER зверху тексту OCR - перетворити виňaтений текст в задруковані об 'єкти PERM SK2ORG/LOCMSC4MISCMST5 ви можете діяти на
  4. Правильна інтеграція DI - AddOcrNer() і ви закінчили
  5. Програмне забезпечення CLI - А Спектр.Консоль command- - додаток для лінії, який просто працює з коробки

Що змінилося з частини 1

flowchart LR
    subgraph Part1["Part 1: Manual"]
        M1[Download models]
        M2[Write tokenizer]
        M3[Wire ONNX]
        M4[BIO decode]
    end

    subgraph Part2["Part 2: NuGet Package"]
        N1["AddOcrNer()"]
        N2[Auto-download]
        N3[Preprocessing]
        N4[Florence-2]
        N5[CLI Tool]
    end

    Part1 -->|"packaged into"| Part2

    style N1 stroke:#090,stroke-width:3px
    style N2 stroke:#090,stroke-width:3px
    style N3 stroke:#f60,stroke-width:3px
    style N4 stroke:#f60,stroke-width:3px
    style N5 stroke:#f60,stroke-width:3px

Частина 1 була освітньою - розуміння того, що робить кожна частина МSK2 Część МSK3 є практичною \ - використання її без роздумів про внутрішні речі \ МSK5


Початок

Установити

dotnet add package Mostlylucid.OcrNer

Услуги реєстрування

І AddOcrNer() метод розширення записує все : OCR, NERM SK2 об 'єднаний трубний кабель МSK3 Флоренція МСК4 зоріобачення М СК5 модельний завантажувач M СК6 і пристрій для обробки зображення М S К 7 Все як одинокі тони M S К 8 всі лінивіші М ็ С К 9 зачаровані M ็ S К 10

Тут - МСК0 - це справжній регистрационний код ServiceCollectionExtensions.cs:

// Option 1: From appsettings.json (reads the "OcrNer" section)
builder.Services.AddOcrNer(builder.Configuration);

// Option 2: Inline configuration
builder.Services.AddOcrNer(config =>
{
    config.EnableOcr = true;
    config.TesseractLanguage = "eng";
    config.MinConfidence = 0.5f;
});

МSK0 - це він. МSK1 - Ніхто не завантажує моделі, МSK2 - немає файлових маршрутів, , - немає ONNX підключення, МСК4 - під капюшоном, MСК5 AddOcrNer() реєструє ці послуги:

// From ServiceCollectionExtensions.cs - what gets registered
services.AddSingleton<ModelDownloader>();       // Auto-downloads models on first use
services.AddSingleton<ImagePreprocessor>();     // ImageSharp-based image enhancement
services.AddSingleton<INerService, NerService>();           // BERT NER from text
services.AddSingleton<IOcrService, OcrService>();           // Tesseract OCR from images
services.AddSingleton<IOcrNerPipeline, OcrNerPipeline>();   // Combined OCR + NER
services.AddSingleton<IVisionService, VisionService>();     // Florence-2 vision

Konfiguration (appsettings.jsonM SK2

{
  "OcrNer": {
    "EnableOcr": true,
    "TesseractLanguage": "eng",
    "MinConfidence": 0.5,
    "MaxSequenceLength": 512,
    "ModelDirectory": "models/ocrner",
    "Preprocessing": "Default"
  }
}

Ось реальний OcrNerConfig поділити ці карти на:

// From OcrNerConfig.cs
public class OcrNerConfig
{
    public string ModelDirectory { get; set; } =
        Path.Combine(AppContext.BaseDirectory, "models", "ocrner");
    public bool EnableOcr { get; set; } = true;
    public string TesseractLanguage { get; set; } = "eng";
    public int MaxSequenceLength { get; set; } = 512;
    public float MinConfidence { get; set; } = 0.5f;
    public string NerModelRepo { get; set; } = "protectai/bert-base-NER-onnx";
    public PreprocessingLevel Preprocessing { get; set; } = PreprocessingLevel.Default;
}

У всіх настроях є розумні початкові параметри. Ви можете закинути весь розділ і все працюєM SK1

І Preprocessing опція контролює покращення зображення перед OCR:

Wartość МSK1 Що це робить МSK2 Коли використовувати
None Жодного попереднього обробки МSK1 Зображення вже оптимізовані МSK2
Minimal Тільки Grayscale Чисті скани МSK2
Default Грейова шкала МSK1 контраст МSK2 острів Більшість образів M( запропоновані
Aggressive Сильний контраст МSK1 острівніше МSK2 збільшення Slikи поганої якості MSК4

Чотири служби

Пакет записує чотири послуги, кожен корисний незалежно від іншогоM SK1 Виберіть той, що підходить для вашого призначення - там ' немає потреби завантажувати ФлоренціюMSC4 якщо все, що вам потрібно - це NER з текстуМSK5

flowchart TD
    subgraph Services
        NER["INerService<br>Text → Entities"]
        OCR["IOcrService<br>Image → Text"]
        PIPE["IOcrNerPipeline<br>Image → Entities"]
        VIS["IVisionService<br>Image → Caption"]
    end

    OCR --> PIPE
    NER --> PIPE

    style PIPE stroke:#090,stroke-width:3px
    style VIS stroke:#f60,stroke-width:3px

Вибирати правильну службу для вашого випадку використання

Головним принципом є ефективність: вибрати найлегший інструмент, який виконує цю функцію . Не завантаження МSK2 модель візуалізації МSK3 МБ, коли OCR-мобіль M SK4 Мб буде виконувати свою функцію

Obsługа МSK1 Що він робить МSK2 розмір моделі Швидкість мSK4 Використовуйте, коли
INerService BERT NER з тексту МSK1 ~430 MB
IOcrService Tesseract OCR з зображеннях МSK2MB МSK3 ♫ ♫ ~100ms ♫ МSK5 Вам потрібен текст із сканування документів ♫, скриншоти ♫
IOcrNerPipeline ОCR, потім NER в одному дзвінку МSK1 Обидві моделі МSK2 ~150ms M У вас є зображення і хочете об 'єкти в один крок МСК5
IVisionService ФлоренціяM SK1 субтитри МSK2 ОКР МSK3 ~450 МБ 5 6 7 Вам потрібно розуміти зображення МSK8 не просто читати текст

NER з тексту (Непотрібні зображення

Якщо у вас вже є текст ( з PDFs , бази даних МSK2 вхід користувача M SK3 ви можете використовувати NER напрямуМSK4 це найшвидший шлях МСК5 без OCR МСК6 без обробки зображень

І INerService інтерфейс простий - один метод

// From INerService.cs
public interface INerService
{
    Task<NerResult> ExtractEntitiesAsync(string text, CancellationToken ct = default);
}

Тут' як його використовувати в своїй власній сферіM SK1

public class MyService
{
    private readonly INerService _nerService;

    public MyService(INerService nerService)
    {
        _nerService = nerService;
    }

    public async Task ProcessDocumentAsync(string text)
    {
        var result = await _nerService.ExtractEntitiesAsync(text);

        foreach (var entity in result.Entities)
        {
            // entity.Label: "PER", "ORG", "LOC", or "MISC"
            // entity.Text: "John Smith"
            // entity.Confidence: 0.9996
            // entity.StartOffset / EndOffset: character positions in the source
        }
    }
}

Результати моделей прості:

// From NerResult.cs / NerEntity.cs
public class NerResult
{
    public string SourceText { get; init; } = string.Empty;
    public List<NerEntity> Entities { get; init; } = [];
}

public class NerEntity
{
    public string Text { get; init; } = string.Empty;     // "John Smith"
    public string Label { get; init; } = string.Empty;    // "PER", "ORG", "LOC", "MISC"
    public float Confidence { get; init; }                 // 0.0 to 1.0
    public int StartOffset { get; init; }                  // Where in the source text
    public int EndOffset { get; init; }                    // End position (exclusive)
}

Перший дзвінок завантажує модель BERT NER (~430MBM SK1 з HuggingFace. Наступні дзвінки використовують зашифровану модель


ОCR + NER Pipeline

Для зображеннях, труба об 'єднує підготування, OCRM SK2 і NER в одному wywołaнніMSC3 IOcrNerPipeline об 'єднує IOcrService і INerService:

// From OcrNerPipeline.cs - the actual pipeline code
public async Task<OcrNerResult> ProcessImageAsync(string imagePath, CancellationToken ct = default)
{
    // Step 1: OCR (includes preprocessing automatically)
    var ocrResult = await _ocrService.ExtractTextAsync(imagePath, ct);

    if (string.IsNullOrWhiteSpace(ocrResult.Text))
        return new OcrNerResult
        {
            OcrResult = ocrResult,
            NerResult = new NerResult { SourceText = string.Empty }
        };

    // Step 2: NER on extracted text
    var nerResult = await _nerService.ExtractEntitiesAsync(ocrResult.Text, ct);

    return new OcrNerResult
    {
        OcrResult = ocrResult,
        NerResult = nerResult
    };
}

Використовуючи його:

var pipeline = serviceProvider.GetRequiredService<IOcrNerPipeline>();

var result = await pipeline.ProcessImageAsync("invoice.png");

// What OCR found
var text = result.OcrResult.Text;           // The full extracted text
var confidence = result.OcrResult.Confidence; // 0.0 to 1.0

// What NER found in that text
foreach (var entity in result.NerResult.Entities)
{
    // [PER] John Smith, [ORG] Microsoft, [LOC] Seattle...
}

Що відбувається під замком

flowchart LR
    IMG[Image bytes]
    PRE["ImageSharp<br>Preprocess"]
    TESS["Tesseract<br>OCR"]
    TOK["WordPiece<br>Tokenize"]
    BERT["BERT NER<br>ONNX"]
    ENT[Entities]

    IMG --> PRE
    PRE --> TESS
    TESS --> TOK
    TOK --> BERT
    BERT --> ENT

    style PRE stroke:#f60,stroke-width:3px
    style BERT stroke:#f60,stroke-width:3px

Перше оброблення зображення

Частина 1 мала необроблені дзвінки Tesseract . В praktyce, як Tesserac, так і FlorenceM SK3 працюють краще з передрозробленими зображеннямиMSC4 Передрозробка по замовчуванню але цілком опціонально - ви можете вимкнути його з Preprocessing = "None" в конфігурації або --preprocess none на CLI.

І ImagePreprocessor використання Зображення (pure C

// From ImagePreprocessor.cs - the actual preprocessing steps
public byte[] Preprocess(byte[] imageBytes, PreprocessingOptions? options = null)
{
    options ??= PreprocessingOptions.Default;
    using var image = Image.Load<Rgba32>(imageBytes);

    image.Mutate(ctx =>
    {
        // Step 1: Upscale small images (Tesseract wants 300+ DPI equivalent)
        if (options.EnableUpscale && (image.Width < options.MinWidth || image.Height < options.MinHeight))
        {
            var scale = Math.Max(
                (float)options.MinWidth / image.Width,
                (float)options.MinHeight / image.Height);
            scale = Math.Min(scale, options.MaxUpscaleFactor);
            ctx.Resize((int)(image.Width * scale), (int)(image.Height * scale),
                KnownResamplers.Lanczos3);
        }

        // Step 2: Grayscale (single channel = faster, more accurate)
        if (options.EnableGrayscale)
            ctx.Grayscale();

        // Step 3: Contrast boost (text stands out from background)
        if (options.EnableContrast && options.ContrastAmount != 1.0f)
            ctx.Contrast(options.ContrastAmount);

        // Step 4: Sharpen (crisp character edges)
        if (options.EnableSharpen)
            ctx.GaussianSharpen(options.SharpenSigma);
    });

    using var ms = new MemoryStream();
    image.SaveAsPng(ms);  // PNG = lossless, no additional artifacts
    return ms.ToArray();
}

Три пресети вбудовані в. PreprocessingOptions клас визначає їх:

// From ImagePreprocessor.cs
public static PreprocessingOptions Default => new();  // Grayscale + 1.5x contrast + sharpen

public static PreprocessingOptions Minimal => new()   // Grayscale only
{
    EnableContrast = false,
    EnableSharpen = false,
    EnableUpscale = false
};

public static PreprocessingOptions Aggressive => new() // For poor quality images
{
    ContrastAmount = 1.8f,
    SharpenSigma = 1.5f,
    MinWidth = 1024,
    MinHeight = 768,
    MaxUpscaleFactor = 4.0f
};
Упередбачуваний МSK1 Коли використовувати МSK2 Що це робить
Default Більшість образів МSK1 Грейова шкала МSK2 1.5 x контраст M+ остришайте світло МСК5
Minimal Чисті скани тільки в чорних діапазонах МSK2
Aggressive Неякісні фотографії МSK1 МSK2x контраст + жорсткий зустріч MSК4 більший масштаб МСК5

Флоренція-2 Vision

Флоренція-2 - це зовсім інший підхід від ТеsseractM SK1, де Tesseract - це спеціалізований OCR-аналізатор, який читає текст символ за символом. модель зору що розуміє ціле зображення. - об 'єкти , сцени МSK2 люди, , і текст

// From IVisionService.cs
public interface IVisionService
{
    Task<VisionCaptionResult> CaptionAsync(string imagePath, bool detailed = true,
        CancellationToken ct = default);
    Task<VisionOcrResult> ExtractTextAsync(string imagePath,
        CancellationToken ct = default);
    Task<bool> IsAvailableAsync(CancellationToken ct = default);
}

Використовуючи його:

var vision = serviceProvider.GetRequiredService<IVisionService>();

// Generate a caption describing the image
var caption = await vision.CaptionAsync("photo.jpg", detailed: true);
if (caption.Success)
{
    // caption.Caption: "A man in a blue suit standing at a podium"
    // caption.DurationMs: how long it took
}

// Extract visible text using Florence-2's built-in OCR
var ocrResult = await vision.ExtractTextAsync("screenshot.png");
if (ocrResult.Success)
{
    // ocrResult.Text: the visible text Florence-2 detected
}

Коли використовувати який

Застосований випадок Тесеракт МSK2IOcrServiceМSK0 Флоренція МSK2 (IVisionService)
Сканування документів МSK0 Найкращий варіант - швидкий МSK2 точний Гаразд, але надмірна кількість
Фотографії знаків Досить МSK1 Краще МSK2 розуміє контекст сцени
Скрині кадри МSK0 Хороша Хороший МSK2
Написування зображення МожешM SK1 не робити цього Найкращий варіант МSK3
Швидка Гвидкий (~100msM SK2 МSK3 Повільніший МSK4s) ≥
Розмір моделі МSK0 ~4МБ МSK2 ~450Мб МСК4

Справа в тому, ефективність: використовувати Tesseract для видобутку документів та текстів (itM SK2s МSK3x швидше з МSK4x меншою модельюMSC5 використовувати Флоренцію-2, коли вам дійсно потрібно зображення розуміння.

Флоренція-2 автоM SK1 завантажує свої моделі MSC2MB) на перший раз, щоб {ModelDirectory}/florence2/.


Як насправді працює модель NER

Якщо ви зацікавлені у тому, що відбувається між текстом " в МSK2 та МSK3 entités out NerService робить це в трьох кроках:

Шаг 1: Маркування WordPiece

БЕРТ не читає слів символи. За замовчанням BertNerTokenizer розділяє ваш текст на частини слів, які BERT розуміє.

// From BertNerTokenizer.cs
// "John Smith works at Microsoft" becomes tokens like:
// [CLS] John Smith works at Micro ##soft [SEP] [PAD] [PAD] ...
//
// Each token tracks its source offset:
// "John"     → chars 0-4
// "Smith"    → chars 5-10
// "Micro"    → chars 20-29  (WordPiece splits "Microsoft")
// "##soft"   → chars 20-29  (same source range as "Micro")

І ## префікс WordPiece нотація, що означає "продовжування попереднього слова ". Це те, як BERT обробляє слова, які він не бачив до цього МSK2 не бачила до цього

Шаг 2: Інференція ONNX

Токенізований вхід проходить через модель BERT як три тягачі. Від NerService.RunInference():

// From NerService.cs
var inputIdsTensor = new DenseTensor<long>(tokenized.InputIds, [1, seqLen]);
var attentionMaskTensor = new DenseTensor<long>(tokenized.AttentionMask, [1, seqLen]);
var tokenTypeIdsTensor = new DenseTensor<long>(tokenized.TokenTypeIds, [1, seqLen]);

var inputs = new List<NamedOnnxValue>
{
    NamedOnnxValue.CreateFromTensor("input_ids", inputIdsTensor),
    NamedOnnxValue.CreateFromTensor("attention_mask", attentionMaskTensor),
    NamedOnnxValue.CreateFromTensor("token_type_ids", tokenTypeIdsTensor)
};

using var results = _session!.Run(inputs);
// Output: logits with shape [1, seqLen, 9] — one of 9 labels per token

Виходи моделі Логіти (raw scores) for 9 possible labels per tokenM SK3

Шаг 3: BIO Tag Decoding

Наклейки 9 відповідають Система BIO - стандартне кодування NER, де B МSK1 Починаючий МSK2 Я = Внутрішній

// From NerService.cs
private static readonly string[] DefaultLabels =
    ["O", "B-MISC", "I-MISC", "B-PER", "I-PER", "B-ORG", "I-ORG", "B-LOC", "I-LOC"];

Ось як зашифровуються речення.

Token:    John    Smith   works   at   Microsoft   in   Seattle
Label:    B-PER   I-PER   O       O    B-ORG       O    B-LOC
Meaning:  Start   Continue Not    Not  Start       Not  Start
          Person  Person   entity entity Org        entity Location

B-PER запускає новий учасник. I-PER продовжується це. Таким чином "John" M SK3 "SmithMSC5 об 'єднуються в один організаційний орган DecodeEntities() метод обробляє це поєднання, включно з фильтрацією довіриM SK1

// From NerService.cs - entity creation with confidence threshold
private void FlushEntity(
    List<NerEntity> entities, string text,
    string type, int start, int end, float confidence)
{
    if (confidence < _config.MinConfidence) return;  // Filter low-confidence

    var entityText = text[start..end].Trim();
    if (string.IsNullOrWhiteSpace(entityText)) return;

    entities.Add(new NerEntity
    {
        Text = entityText,
        Label = type,
        Confidence = confidence,
        StartOffset = start,
        EndOffset = end
    });
}

Auto-Download: Як це працює

Всі моделі завантажуються автоматично після першого використання. Не потрібна ручна інсталяціяM SK1

flowchart TD
    CALL["First API call"]
    CHECK{"Files exist<br>in cache?"}
    YES[Use cached model]
    NO["Download to .tmp file"]
    MOVE["Atomic rename<br>.tmp → final"]

    CALL --> CHECK
    CHECK -->|Yes| YES
    CHECK -->|No| NO
    NO --> MOVE
    MOVE --> YES

    style NO stroke:#f60,stroke-width:3px
    style MOVE stroke:#090,stroke-width:3px

І ModelDownloader завантаження з HuggingFace (NER modelM SK1 і GitHub (tessdata). Він використовує атомну .tmp шаблон - якщо завантаження перервано , жодних пошкоджених файлів не залишилося позадуM SK2

// From ModelDownloader.cs - atomic download pattern
await using var fileStream = new FileStream(tempPath, FileMode.Create,
    FileAccess.Write, FileShare.None, 81920, true);
// ... stream download to .tmp file ...
await fileStream.FlushAsync(ct);
fileStream.Close();

File.Move(tempPath, localPath, overwrite: true);  // Atomic rename

Початкова точністьキャッシュу: {AppBaseDir}/models/ocrner/

models/ocrner/
  ner/
    model.onnx      (~430MB - BERT NER)
    vocab.txt       (~230KB - WordPiece vocabulary)
    config.json     (~1KB - label mapping)
  tessdata/
    eng.traineddata (~4MB - English OCR data)
  florence2/
    ...             (~450MB - Vision model files)

Архітектура

Усе - це одинтон з ліницькою іініціалізацією. дорогі ресурси M SK1ONNX InferenceSession, TesseractEngine, Флоренція -2 модель МSK2 створені один раз при першій використанні і перероблені на весь термін використання

flowchart TD
    DI["AddOcrNer()"]

    DI --> MD["ModelDownloader<br>(singleton)"]
    DI --> PP["ImagePreprocessor<br>(singleton)"]
    DI --> NER["NerService<br>(singleton)"]
    DI --> OCR["OcrService<br>(singleton)"]
    DI --> PIPE["OcrNerPipeline<br>(singleton)"]
    DI --> VIS["VisionService<br>(singleton)"]

    MD --> NER
    MD --> OCR
    PP --> OCR
    NER --> PIPE
    OCR --> PIPE

    style DI stroke:#090,stroke-width:3px

Безпека ниток: всі послуги SemaphoreSlim для інициалізації. Багато потоків, які запускають службу одночасно при першій користуванні, спричиняють лише один завантаження /завантаження МSK2

// From NerService.cs - lazy init pattern used by all services
private async Task EnsureInitializedAsync(CancellationToken ct)
{
    if (_initialized) return;           // Fast path: already loaded

    await _initLock.WaitAsync(ct);      // Only one thread enters
    try
    {
        if (_initialized) return;       // Double-check after lock

        var paths = await _downloader.EnsureNerModelAsync(ct);
        _tokenizer = new BertNerTokenizer(paths.VocabPath, _config.MaxSequenceLength);
        _session = new InferenceSession(paths.ModelPath, sessionOptions);
        _initialized = true;
    }
    finally { _initLock.Release(); }
}

Програмне забезпечення CLI

Репо включає в себе Command-line інструмент, збудований з Спектр.Консоль. Це МSK1 спроектовано як МSK2 вершина успіху " \ \ - просто передайте ваші дані і це працює \

Швидкий старт

cd Mostlylucid.OcrNer.CLI

# NER from text (auto-detected)
dotnet run -- "John Smith works at Microsoft in Seattle"

# OCR from an image (auto-detected)
dotnet run -- invoice.png

# Explicit commands
dotnet run -- ner "Marie Curie won the Nobel Prize in Stockholm"
dotnet run -- ocr scan.png
dotnet run -- caption photo.jpg

Розумне маршрутизування: автомат CLI - визначає ваші наміри Program.cs:

// From Program.cs - smart routing logic
if (IsImageFile(args2[0]) || IsGlobPattern(args2[0]) || Directory.Exists(args2[0]))
{
    args2 = ["ocr", .. args2];   // Image file → ocr command
}
else
{
    args2 = ["ner", .. args2];   // Text string → ner command
}

Якщо передати текстову стрічку, вона запускає NER. Якщо передувати файл з зображенням , globM SK3 або каталогі МSK4 він запускає OCR MSC5 NER

Три команди

Команда МSK1 Що він робить МSK2 Мотор Швидкість
ner <text> Вирізаємо елементи з тексту BERT NER МSK2ONNXM SK3 МSK4 ~50ms МSK6
ocr <path> ОКР МSK1 NER з зображеннях МSK2 Тесеракт + BERT မ်SK4 мSK5м M
caption <path> Напис зображення МSK1 опціональний OCR МSK2 ФлоренціяM SK3 (ONNX)

Теsseract - це початковий OCR-аналізатор тому що це 's МSK1x швидше і оптимізоване для тексту документу МSK2 Флоренція -2 є для, коли вам потрібно розуміти зображення МСК4 заголовки М СК5 текст сцени M СК6 фото знаків MСК7

Реальний Output

Ось реальний результат запуску CLI:

dotnet run -- ner "John Smith works at Microsoft in Seattle, Washington."
Input: John Smith works at Microsoft in Seattle, Washington.

╭──────┬────────────┬────────────┬──────────╮
│ Type │ Entity     │ Confidence │ Position │
├──────┼────────────┼────────────┼──────────┤
│ PER  │ John Smith │ 100%       │ 0-10     │
│ ORG  │ Microsoft  │ 100%       │ 20-29    │
│ LOC  │ Seattle    │ 100%       │ 33-40    │
│ LOC  │ Washington │ 100%       │ 42-52    │
╰──────┴────────────┴────────────┴──────────╯
dotnet run -- ner "Marie Curie won the Nobel Prize in Stockholm"
╭──────┬─────────────┬────────────┬──────────╮
│ Type │ Entity      │ Confidence │ Position │
├──────┼─────────────┼────────────┼──────────┤
│ PER  │ Marie Curie │ 100%       │ 0-11     │
│ MISC │ Nobel Prize │ 100%       │ 20-31    │
│ LOC  │ Stockholm   │ 100%       │ 35-44    │
╰──────┴─────────────┴────────────┴──────────╯

Виход JSON

Заspeicherти до JSON для програмного використання:

dotnet run -- ner "John Smith works at Microsoft in Seattle, Washington." -o results.json
{
  "sourceText": "John Smith works at Microsoft in Seattle, Washington.",
  "entityCount": 4,
  "entities": [
    {
      "type": "PER",
      "text": "John Smith",
      "confidence": 0.9996,
      "startOffset": 0,
      "endOffset": 10
    },
    {
      "type": "ORG",
      "text": "Microsoft",
      "confidence": 0.9988,
      "startOffset": 20,
      "endOffset": 29
    },
    {
      "type": "LOC",
      "text": "Seattle",
      "confidence": 0.9991,
      "startOffset": 33,
      "endOffset": 40
    },
    {
      "type": "LOC",
      "text": "Washington",
      "confidence": 0.9988,
      "startOffset": 42,
      "endOffset": 52
    }
  ]
}

Обробка пакетів

Обробляйте багатооб 'ємні зображення за допомогою шаблонів чи каталогів

# All PNGs in a directory
dotnet run -- ocr "scans/*.png" -o results.json

# All images in a folder
dotnet run -- ocr ./documents/

# Batch captioning with Florence-2
dotnet run -- caption "photos/*.jpg" --ocr -o captions.md

Усі варіанти CLI

Флаг МSK1 Застосовується до МSK2 Описание
-c ner, ocr Minimalний початковий рівень впевненості компанії
--language ocr мова Tesseract ( наприклад eng, fra)
--max-tokens ner, ocr Максимальна тривалість послідовності BERT
--model-dir ner, ocr, caption Запис модельного каталогу пам 'яті
-p, --preprocess ocr, caption Установлено для попереднього обробки none, minimal, default, aggressive
-q, --quiet ner, ocr, caption Тихий режим МSK1знижений вихід з консолі МSK2
-o ner, ocr, caption вихідний шлях файлу (.txt, .md, .json)
--ocr caption Далі запустите OCR під час команди з заголовком
--ner caption Вирізає NER з тексту OCR ( упрощує --ocr)

Продукція: Квантовані моделі і щоM SK1 Наступне

На даний момент модель NER має повну protectai/bert-base-NER-onnx (~430MBM SK1 Для багатьох випадків використання - особливо на ресурсі МSK3 при обмежених машинах або при обробці великих об 'ємів кількісно (INTM SK1 версія тієї ж моделі була б значно швидша з мінімальним втратою точності

Runtime ONNX підтримує INT8 квантування з-за коробки ,, що зазвичай зменшує розмір моделі на M SK2x і покращує швидкість виведення на \2-3x на процесорі. Це на карті NerModelRepo опція конфігурації вже підтримує вказування на іншу HuggingFace репо, тому, коли ви опублікуєте кількісну модель, ви'd просто змінитеM SK2

{
  "OcrNer": {
    "NerModelRepo": "protectai/bert-base-NER-onnx-quantized"
  }
}

Архітектура розроблена для цього. - замінити модель.


Найвизначніша картина: Де це підходить

Цей пакет - одноступенча труба: один OCR двигун , один NER-модель МSK2 один опціональний візуальний модель

Для більш складних сценаріїв - читайте текст з будь-що ( рукописні нотатки , фотографії білих таблиць МSK2 низький M SK3 високоякісні камерні знімки ), з мультиплікатором МSK5 консенсус OCR двигуна LucidRAG. Те, що ' це місце, де проживає виробництво МSK2 сорта МСК3 багаторазовий М СК4 фазова версія цієї роботи MСК5

Що's НаступнеM SK1 Мультимоdal LLM

Флоренція-2 є теперішньою межою для локального бачення в цьому пакетіM SK1 Наступним логічним кроком є мультимодальний LLM - модель, яка може бачити зображення і про причину цього в природному мові. Замість відокремленого OCR MSC1 NER крокиM SK2 ви' надсилаєте зображення безпосередньо і запитуєте про структурне виділення

Ось як би API виглядало:

// Hypothetical future IMultimodalService
public interface IMultimodalService
{
    Task<StructuredExtractionResult> ExtractAsync(
        string imagePath,
        string prompt = "Extract all people, organizations, and locations from this image. Return as JSON.",
        CancellationToken ct = default);
}

// Usage
var multimodal = serviceProvider.GetRequiredService<IMultimodalService>();
var result = await multimodal.ExtractAsync("business-card.jpg");

// result.Entities: [{ "John Smith", PER }, { "Acme Corp", ORG }, { "New York", LOC }]
// result.RawText: "John Smith, VP Engineering, Acme Corp, New York, NY 10001"
// result.Summary: "Business card for John Smith at Acme Corp in New York"

Малі локальні мультиmodaльні моделі (подібні Phi-3.5-vision або ЛЛАВА) стають достатньо добрими для цього . Торгівля МSK2off завжди одна й та сама МSK3 більша модель Хіба = розумніша, але повільніша \ . Правильний вибір залежить від вашого бюджету на затримку і вимог до точності

flowchart LR
    subgraph Staged["Staged Approach: Pick Your Level"]
        T1["Tesseract OCR<br>4MB | ~100ms<br>Text extraction"]
        T2["BERT NER<br>430MB | ~50ms<br>Entity extraction"]
        T3["Florence-2<br>450MB | ~1-3s<br>Image understanding"]
        T4["Multimodal LLM<br>2-8GB | ~5-30s<br>Full reasoning"]
    end

    T1 --> T2
    T2 --> T3
    T3 -.->|"future"| T4

    style T1 stroke:#090,stroke-width:2px
    style T2 stroke:#090,stroke-width:2px
    style T3 stroke:#f60,stroke-width:2px
    style T4 stroke:#999,stroke-width:2px,stroke-dasharray: 5 5

Кожна шкала додає можливостей за рахунок вартості розміру та затримки. У даний момент пакет охоплює тривиміри M SK1 шкало МSK2 це місце, де мультиmodaльні LLM приходять в МSK3 і де LucidRAG це заголовок.


Ресурс

Цей пакет:

Частина 1:

Відлежність:

Подібні статті:

  • Трійна труба МСК0Tier - Коли вам потрібно більше, ніж просто OCR
  • Reduced RAG - Де виділені об 'єкти вписуються у загальну картину
  • LucidRAG - Полна багатофазова труба для виробництва
Finding related posts...
logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.