Изграждане на тръбопровода за данни за разузнаване на ръба: текст до структурирани субекти в милисекунди. При проектирането на Едно от основните ограничения, с които се сблъсках, беше "данъкът за превод" - изчислителният обем на разчитането на масивни, монолитни модели на голям език (LLM) за изпълнение на задачи, за които никога не са били оптимално проектирани. FogAI В една наивна архитектура, разработчикът може да маршрутизира сурови дневници на сензори или чат контекст към модел на параметър 7B или 8B с покана като "Extract all the field units, locations, and timestamps from the following text." Има две очевидни проблеми с този подход за Edge AI: Данъкът за извод: Извършването на проста екстракция с параметри 8B изгаря батерията, запълва VRAM и въвежда латентност (300ms+ на заявка) само за да върне JSON низ. Халюцинации: LLMs са генериращи.Те предполагат кой токен идва след това, което води до структурни несъответствия и измислени субекти. За да се справим с този проблем, създадохме специален Използването на модел (194M параметри). работи чисто на , този слой преодолява пропастта между суровите текстови потоци и структурираните действащи данни - всичко това без един Python wrapper. Knowledge Extraction Layer knowledgator/gliner-bi-base-v2.0 MNN Ето архитектурното разпадане на начина, по който извличам "магическата" скорост. Пробивът на Bi-Encoder Класическите модели на NER изискват предварително да дефинирате субектите (напр. , , ) по време на обучението. моментът, в който се нуждаете от потребителска единица като или Моделът се разпада. PERSON ORG LOC WELDING DEFECT RADIO FREQUENCY GLiNER (Generalist and Lightweight Named Entity Recognition) разрешава това с помощта на Той физически разделя процеса на кодиране по средата: Bi-Encoder Architecture Text Encoder: Създава богати контекстни вграждания за суровия входящ текст. Label Encoder: Създава вграждания за списъка на субектите, които искате да намерите. Защо това архитектурно разделение е шедьовър на Edge? Caching. В крайния възел за проследяване на данни на работното място, желаните от вас етикети (напр. ) рядко се променя от милисекунди на милисекунди. Тъй като кодерите за текст и етикет са разделени, . ['worker', 'forklift', 'safety_vest', 'pallet'] FogAi caches the Label Embeddings in RAM За всеки нов поток от текст, който пристига, Gateway трябва само да изпълнява текстовия кодиращ. , независимо дали търсите 5 типа субекти или 500. Constant-Time Inference Пълни потоци от данни: Zero Python FogAi използва JNI и gRPC за директно изпълнение на MNN inference.The работен поток е напълно лишен от тежки Python runtime overhead: Raw Text Ingest -> Raw string пристига в Vert.x Gateway. JNI / C++ Hand-off -> Стрийтът се предава директно чрез буфери за памет извън купчина. MNN Text Encoder -> Gliner-bi-base-v2.0 ONNX графиката се изпълнява чрез MNN runtime (което е напълно ускорено за Edge CPU и NPU). Vector Dot Product -> C++ Engine изчислява проста матрица за сходство на продукта Dot между новите Text Embeddings и предварително изчислените Label Embeddings. Структуриран изход -> Чист JSON полезен товар, съдържащ етикетираните диапазони, се насочва обратно към маршрутизатора за < 50 милисекунди. Всичко това се случва, без данните да докосват облака. Бенчмаркиране на данъка върху прехвърлянето Бенчмаркиране на данъка върху индексацията: три модела в пръстена Аз не просто теоретизирах „данъка за изчисление“ – ние го измервахме. Файлът на Репозиторията на Python Benchmarking скриптове за извличане на от една стандартна фраза. pycompare FogAi ['animal', 'location', 'time', 'date'] Нека да разгледаме тримата състезатели в ринга: Тежкото тегло (общ LLM): Qwen2.5-0.5B-Инструкция Специализираната тежка тежест: numind / NuExtract-1.5 (фино регулирана екстракция LLM) Agile Bi-Encoder (двигател на FogAi): GLiNER-194M Ето и основните емпирични данни: 1 от Закона за ДДС ( ) pycompare/test_llm_perf.py Модел: Qwen2.5-0.5B-Инструкция Архитектура: Generative Causal LM Бързи токени за вход: 53 Изработени токени: 100 Общо време за изчисление: 3,524.42 ms (Да, 3.5 секунди) RAM отпечатък: 1,116.77 MB Резултатът: LLM халюцинира, излъчвайки JSON блок, който напълно пропусна "кафявата лисица" и "мързеливото куче", последвани от 50 токена на нежелан вътрешен монолог за това как планира да извлече субектите. Специализираният LLM (NuExtract 1.5) Модел: numind / NuExtract-1.5 Архитектура: Generative Causal LM (Fine-tuned за JSON извличане) Бързи токени за вход: 55 Произведени токени: 30 Общо време на изчисление: ~1,200.00 ms RAM отпечатък: ~1,200.00 MB Резултатът: Точна екстракция на субектите в правилния JSON формат, но все още страда от авторегресивно генериране на токени.Той е по-бърз от Qwen, защото халюцинира по-малко, генерирайки по-малко изходни токени, но все още отнема повече от секунда. Създаване на съвместна система за изчисляване на данните ( ) pycompare/test_gliner_perf.py Модел: knowledgator/gliner-bi-base-v2.0 Архитектура: Bi-Encoder Приблизителни токени за въвеждане: 22 (текст + етикети) Общо време за изчисление (Python): 50.83 ms Общо време за отчитане (JNI/C++ Web Gateway): ~750.00 ms (включително HTTP рамкиране, опашка и мемкопиране извън купчина) RAM отпечатък: 824.11 MB Резултатът: Чиста, перфектно структурирана екстракция на {животно: "бърза кафява лисица", местоположение: "Ню Йорк", време: "5 PM", дата: "Понеделник"}. Съдът: Вгражданията са кръвта на векторните бази данни Чрез разтоварване на Knowledge Extraction на GLiNER, FogAi ускорява тръбопровода с до (3500ms срещу 50ms в сурово изпълнение) в сравнение с общ LLM, и превъзхожда фино настроен екстракция LLMs (като NuExtract) чрез напълно заобикаляне на авторегресивната бутилка. 6,800% Но грубата екзекуция е само половината от битката. How do we deploy it? Тестът за интеграция на Gateway: Тестване на всяка топология (нодули A, B и C) В архитектурата FogAi изградих три различни топологии за разполагане, за да тествам интеграцията на GLiNER. Тип А (In-Process JNI): Извършва GLiNER изрично в C++ чрез директен достъп до паметта (off-heap memory buffers) в същия JVM като Vert.x API Gateway. Тип B (Out-of-Process C++ gRPC): Извършва GLiNER в автономна C++ микроуслуга (използвайки или MNN или ONNX runtime) и комуникира с Gateway чрез HTTP/2. Тип C (Out-of-Process Python gRPC): Изпълнява GLiNER в стандартна Python базирана gRPC микроуслуга, използвайки ONNX runtime. Когато тествах всичките три възли чрез Vert.x API Gateway, резултатите бяха окончателни: Averaged per request under load. The combined overhead of Protobuf serialization, inter-process HTTP/2 networking, and the crushing weight of the Python Global Interpreter Lock (GIL) created a massive bottleneck. Type C (Out-of-Process Python gRPC): 3,200 ms - 4,500 ms Averaged per request under load. Even with a hyper-optimized C++ backend, the overhead of Protobuf serialization/deserialization and inter-process HTTP/2 networking created a massive bottleneck. Under stress tests ( ), the network stack overhead resulted in queue pileups for a model that normally takes 50ms to run natively. Type B (Out-of-Process C++ gRPC): 1,250 ms - 2,100 ms test_integration.sh Sustained end-to-end latency the HTTP Web Gateway routing, EDF queueing, Type A (In-Process JNI): ~750.00 ms including the "Vanilla" safety checks, and memory mapping. The direct off-heap C++ memory handoff bypassed the networking and serialization layer entirely. Чрез обработка на GLiNER на natively на крайния възел тип A вътре в MNN, аз автоматично и получават достъп до плътните контекстуални вграждания на тези субекти по време на напредъка. Generative LLMs не генерират изходящи вграждания на токени за индексиране на бази данни без вторични модели за вграждане. : Мога незабавно да конструирам временни графики на знанието от сурови сензорни източници в областта. БЕЗПЛАТНО НАЧАЛО unfair advantage Разчитането на LLMs за локализирано извличане на знания на крайния възел е злоупотреба с хардуер. Експортиране на GLiNER в C++ MNN За да постигна тези скорости на интеграция на JNI без Python, трябва да конвертирам модела HuggingFace GLiNER в MNN Избягвам бъговете за проследяване на ONNX динамични форми в по-новите версии на PyTorch, като взема експлицитния слой за проследяване ONNX директно от HuggingFace и използвам . .mnn MNNConvert Аз съм предоставил този точен сценарий за преобразуване в В този репозиторий: scripts/convert_gliner_to_mnn.sh #!/bin/bash ONNX_MODEL="models_onnx/gliner-bi-v2/onnx/model.onnx" MNN_DIR="models_mnn/gliner-bi-v2" mnnconvert -f ONNX --modelFile "$ONNX_MODEL" --MNNModel "$MNN_DIR/model.mnn" --bizCode MNN copy models_onnx/gliner-bi-v2/*.json "$MNN_DIR/" Проверете сами магията Можете да изпълнявате бенчмаркове на Python на собствената си машина. Клониране на FogAi хранилището, навигация до , и изпълнявайте тестовете, за да видите данъка за изчисление на живо: pycompare git clone https://github.com/NickZt/FogAi.git cd FogAi python3 -m venv venv && source venv/bin/activate pip install psutil gliner transformers accelerate python3 pycompare/test_gliner_perf.py python3 pycompare/test_llm_perf.py Бонус: Вмъкване на FogAi в Open WebUI Тъй като FOGAI излага ( от ), дори не е нужно да пишете персонализиран клиентски код, за да взаимодействате с него. настройка в хранилището, което завърта популярните чат интерфейси, посочващи директно на Gateway. OpenAI-compatible API /v1/chat/completions docker-compose Уверете се, че имате Docker инсталиран на вашия компютър. Навигация към UI директорията и стартиране на услугите: cd UI docker-compose up -d Open your browser and start chatting: : Open WebUI http://localhost:3000 : (Password is simply ) Lobe Chat http://localhost:3210 fogai Интерфейсите автоматично ще достигнат до , открийте работещите модели MNN и ONNX и ги извикайте, сякаш те се изпълняват в облака. http://host.docker.internal:8080/v1