{"id":42802430,"url":"https://github.com/datalevin/dtlvnative","last_synced_at":"2026-04-01T18:25:22.468Z","repository":{"id":64704907,"uuid":"405541656","full_name":"datalevin/dtlvnative","owner":"datalevin","description":"The native dependency of Datalevin database","archived":false,"fork":false,"pushed_at":"2026-03-30T14:43:09.000Z","size":950,"stargazers_count":6,"open_issues_count":2,"forks_count":5,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-03-30T15:08:47.659Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/datalevin.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-09-12T04:01:32.000Z","updated_at":"2026-03-30T14:43:13.000Z","dependencies_parsed_at":"2023-12-31T01:36:57.895Z","dependency_job_id":"d80244fb-e5c4-4017-80db-9278dd8ee679","html_url":"https://github.com/datalevin/dtlvnative","commit_stats":{"total_commits":96,"total_committers":1,"mean_commits":96.0,"dds":0.0,"last_synced_commit":"b55a5935cbeaae18ad9a485a12718c4694afc8ed"},"previous_names":["datalevin/dtlvnative","juji-io/dtlvnative"],"tags_count":134,"template":false,"template_full_name":null,"purl":"pkg:github/datalevin/dtlvnative","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datalevin%2Fdtlvnative","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datalevin%2Fdtlvnative/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datalevin%2Fdtlvnative/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datalevin%2Fdtlvnative/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/datalevin","download_url":"https://codeload.github.com/datalevin/dtlvnative/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datalevin%2Fdtlvnative/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31290841,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-30T03:15:20.885Z","updated_at":"2026-04-01T18:25:22.457Z","avatar_url":"https://github.com/datalevin.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dtlvnative\n\nProvides pre-built native dependencies for\n[Datalevin](https://github.com/juji-io/datalevin) database. This is done by\npackaging the compiled native libraries and JavaCPP JNI library files in the\nplatform specific JAR files.\n\nIn addition to JavaCPP's JNI library, these native libraries are included:\n\n* [`dlmdb`](https://github.com/huahaiy/dlmdb) a fork of\n  [LMDB](https://www.symas.com/mdb) key value storage library.\n* [`usearch`](https://github.com/unum-cloud/USearch) a vector indexing and\n  similarity search library that is exposed directly for callers.\n* [`llama.cpp`](https://github.com/ggml-org/llama.cpp) built as a CPU-only\n  GGUF runtime for embeddings and prompt-based text generation.\n* `dtlv` wraps DLMDB. It implements Datalevin iterators, counters and\n  samplers.\n\nThe following platforms are currently supported:\n\n* macosx-arm64\n* freebsd-x86_64\n* linux-arm64\n* linux-x86_64\n* windows-x86_64\n\nThe name of the released JAR is `org.clojars.huahaiy/dtlvnative-PLATFORM`, where\n`PLATFORM` is one of the above.\n\nVector support using usearch on Windows is experimental.\n\n## llama.cpp text + embedding\n\n`dtlvnative` packages the CPU backend of `llama.cpp` with OpenMP enabled. The\npackaged native API now supports embedding models, decoder-only text models for\nprompt-based generation, and multimodal OCR with PaddleOCR-VL GGUF models.\n\n### Embedding API\n\n| Function | Description |\n|---|---|\n| `dtlv_llama_embedder_create` | Load a GGUF model and create an embedder |\n| `dtlv_llama_embedder_n_embd` | Return the embedding dimension |\n| `dtlv_llama_embedder_n_ctx` | Return the context size (max tokens) |\n| `dtlv_llama_token_count` | Count tokens for a string without allocating |\n| `dtlv_llama_tokenize` | Tokenize a string into a caller-owned `int[]` buffer |\n| `dtlv_llama_detokenize` | Convert tokens back to a UTF-8 string |\n| `dtlv_llama_embed` | Compute an embedding for a single string |\n| `dtlv_llama_embed_batch` | Compute embeddings for multiple strings in one call |\n| `dtlv_llama_embedder_destroy` | Free the embedder |\n\nThe model must be a GGUF embedding model. The current smoke test uses\n`multilingual-e5-small-Q8_0.gguf`.\n\n`dtlv_llama_embedder_create` takes `model_path`, `n_ctx`, `n_batch`,\n`n_threads`, and `normalize`. Pass `0` for `n_ctx` and `n_batch` to use model\ndefaults. A non-zero `normalize` returns L2-normalized embeddings.\n\n### Single embedding\n\n```java\nDTLV.dtlv_llama_embedder embedder = new DTLV.dtlv_llama_embedder();\nint rc = DTLV.dtlv_llama_embedder_create(\n        embedder,\n        \"multilingual-e5-small-Q8_0.gguf\",\n        0, 0, 4, 1);\n\nint nEmbd = DTLV.dtlv_llama_embedder_n_embd(embedder);\nfloat[] output = new float[nEmbd];\nrc = DTLV.dtlv_llama_embed(embedder, \"query: hello world\", output, nEmbd);\n\nDTLV.dtlv_llama_embedder_destroy(embedder);\n```\n\n### Token counting and tokenization\n\n```java\n// check token count before embedding\nint nTokens = DTLV.dtlv_llama_token_count(embedder, text);\nint maxTokens = DTLV.dtlv_llama_embedder_n_ctx(embedder);\n\n// tokenize, truncate, detokenize\nint[] tokens = new int[maxTokens];\nint actual = DTLV.dtlv_llama_tokenize(embedder, text, tokens, maxTokens);\nif (actual \u003e maxTokens) {\n    // truncate to fit\n    actual = maxTokens;\n}\nbyte[] buf = new byte[text.length() * 4];\nint len = DTLV.dtlv_llama_detokenize(embedder, tokens, actual, buf, buf.length);\nString truncated = new String(buf, 0, len, StandardCharsets.UTF_8);\n```\n\n### Batch embedding\n\n```java\nPointerPointer texts = new PointerPointer(\"query: hello\", \"query: world\");\nint nTexts = 2;\nfloat[] output = new float[nTexts * nEmbd];\nrc = DTLV.dtlv_llama_embed_batch(embedder, texts, nTexts, output, output.length);\n// output[0..nEmbd-1] = embedding for \"query: hello\"\n// output[nEmbd..2*nEmbd-1] = embedding for \"query: world\"\n```\n\nThe Java test in `src/java/datalevin/dtlvnative/Test.java` will use\n`target/embedding-models/multilingual-e5-small-Q8_0.gguf` if present, fall back\nto a repository-root copy if present, and otherwise download the model from\nHugging Face before running the embedding smoke test.\n\n### Text generation API\n\nThe text-generation API is aimed at decoder-only instruction models such as\nQwen 3.5 0.8B Instruct in GGUF format.\n\n| Function | Description |\n|---|---|\n| `dtlv_llama_generator_create` | Load a GGUF decoder-only text model |\n| `dtlv_llama_generator_n_ctx` | Return the context size |\n| `dtlv_llama_generator_token_count` | Count tokens for a prompt/document |\n| `dtlv_llama_generate` | Generate text for a raw prompt |\n| `dtlv_llama_summarize` | Build a summarization prompt and generate a summary |\n| `dtlv_llama_generator_destroy` | Free the generator |\n\n`dtlv_llama_generate` and `dtlv_llama_summarize` return the number of UTF-8\nbytes written to the caller-owned output buffer. When `n_predict \u003c= 0`, they\ndefault to a 128-token generation budget. Prompt text that exceeds the context\nsize is automatically truncated to the leading tokens that fit.\n\n```java\nDTLV.dtlv_llama_generator generator = new DTLV.dtlv_llama_generator();\nint rc = DTLV.dtlv_llama_generator_create(\n        generator,\n        \"Qwen3.5-0.8B-Instruct-Q4_K_M.gguf\",\n        2048, 0, 4);\n\nbyte[] output = new byte[8192];\nint len = DTLV.dtlv_llama_summarize(\n        generator,\n        \"Datalevin embeds data locally and can pair vector search with LMDB-backed storage.\",\n        128,\n        output,\n        output.length);\n\nString summary = new String(output, 0, len, StandardCharsets.UTF_8);\nDTLV.dtlv_llama_generator_destroy(generator);\n```\n\nIf you want to supply your own instruction prompt instead of the built-in\nsummary helper, call `dtlv_llama_generate` directly.\n\n### Vision / OCR API\n\nThe vision API is aimed at multimodal GGUF models with a matching projector\nGGUF, such as `PaddleOCR-VL-1.5-GGUF`.\n\n| Function | Description |\n|---|---|\n| `dtlv_llama_vision_generator_create` | Load a multimodal text GGUF and matching `mmproj` GGUF |\n| `dtlv_llama_vision_generator_n_ctx` | Return the context size |\n| `dtlv_llama_vision_generate` | Generate text for a single image plus prompt |\n| `dtlv_llama_ocr` | Run OCR with the built-in `OCR:` prompt |\n| `dtlv_llama_vision_generator_destroy` | Free the vision generator |\n\n`dtlv_llama_vision_generator_create` takes `model_path`, `mmproj_path`,\n`n_ctx`, `n_batch`, `n_threads`, `image_min_tokens`, and `image_max_tokens`.\nPass `0` for the numeric tuning parameters to keep the model defaults. The\nruntime is CPU-only in this package.\n\n`dtlv_llama_vision_generate` and `dtlv_llama_ocr` return the number of UTF-8\nbytes written to the caller-owned output buffer. The image prompt is single\nimage only. If the prompt passed to `dtlv_llama_vision_generate` does not\ncontain the multimodal marker, the native layer prepends it automatically.\n\n```java\nDTLV.dtlv_llama_vision_generator generator = new DTLV.dtlv_llama_vision_generator();\nint rc = DTLV.dtlv_llama_vision_generator_create(\n        generator,\n        \"PaddleOCR-VL-1.5.gguf\",\n        \"PaddleOCR-VL-1.5-mmproj.gguf\",\n        0, 0, 4, 0, 0);\n\nbyte[] output = new byte[8192];\nint len = DTLV.dtlv_llama_ocr(\n        generator,\n        \"page.png\",\n        16,\n        output,\n        output.length);\n\nString text = new String(output, 0, len, StandardCharsets.UTF_8);\nDTLV.dtlv_llama_vision_generator_destroy(generator);\n```\n\n### Local llama smoke test\n\nTo refresh the JavaCPP platform libraries and run the local llama smoke tests\nwith a real decoder model:\n\n```bash\nscript/test-llama-summarization --text-model=target/text-models/qwen2.5-0.5b-instruct-q5_k_m.gguf\n```\n\nThe script runs `Test.java` with `--llama-only`, so it covers both the llama\nembedding smoke test and the summarization flow. If you prefer, set\n`DTLV_TEXT_MODEL_PATH=/abs/path/model.gguf` instead of passing `--text-model`.\n\n### OCR smoke test\n\nTo refresh the JavaCPP platform libraries and run only the PaddleOCR-VL smoke\ntest:\n\n```bash\nscript/test-llama-ocr \\\n  --vision-model=/path/to/PaddleOCR-VL-1.5.gguf \\\n  --vision-mmproj=/path/to/PaddleOCR-VL-1.5-mmproj.gguf \\\n  --ocr-image=/path/to/image.png \\\n  --ocr-n-predict=16\n```\n\nThe OCR script runs `Test.java` with `--ocr-only`, so it skips LMDB, usearch,\nembedding, and summarization. It also prints the extracted OCR text. You can\nset `DTLV_VISION_MODEL_PATH`, `DTLV_VISION_MMPROJ_PATH`, `DTLV_OCR_IMAGE_PATH`,\nand `DTLV_OCR_N_PREDICT` instead of passing the flags explicitly.\n\nFor CPU-only smoke tests, keep `--ocr-n-predict` small. `16` is a practical\ndefault for checking that OCR works end to end. Large document images are much\nslower than small or resized inputs, so for quick validation it helps to reduce\nthe longest edge to around 512 pixels first.\n\n## Additional dependencies\n\nRight now, the included shared libraries depend on some system libraries.\n\n* `libc`\n* `libmvec`\n* `libomp` or `libgomp`\n\nWe bundle `libomp` in the Jar. However, on systems that the bundled library is\nnot working, or `libc` is not available, you will have to install them yourself.\nFor example, on Ubuntu/Debian, `apt install libgomp1`, or `apt install gcc-12\ng++-12`; on MacOS, `brew install libomp libllvm`\n\n## License\n\nCopyright © 2021-2026 Huahai Yang\n\nThis program and the accompanying materials are made available under the\nterms of the Eclipse Public License 2.0 which is available at\nhttp://www.eclipse.org/legal/epl-2.0.\n\nThis Source Code may also be made available under the following Secondary\nLicenses when the conditions for such availability set forth in the Eclipse\nPublic License, v. 2.0 are satisfied: GNU General Public License as published by\nthe Free Software Foundation, either version 2 of the License, or (at your\noption) any later version, with the GNU Classpath Exception which is available\nat https://www.gnu.org/software/classpath/license.html.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatalevin%2Fdtlvnative","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdatalevin%2Fdtlvnative","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatalevin%2Fdtlvnative/lists"}