Lucida (BiRefNet) β€” Karume

What is this

A background-removal distribution, converted into the WebGPU inference runtime Karume's container format (a graph shard carrying the graph JSON in __metadata__, followed by the weight shards it names). Runs as-is in the browser and in Deno.

The weights are a BiRefNet fine-tune aimed at camouflage, transparency, text/logos and illustration.

  • One graph, one call: pixels in, an 8-bit alpha matte out, at the same size as the image you handed over.
  • One model per input resolution. The resolution is baked into the graph (window masks and padding constants are per-resolution), so it is picked with model, not at call time. Each model declares its own resize target below; the bigger one holds more detail at the edges and costs more GPU memory and time.
  • Pre- and post-processing are included. The pipeline resizes to 1024 Γ— 1024 for the default model 1024, normalizes with the constants below, then takes the sigmoid of the logits and scales the matte back to the original resolution. Decoding PNG / JPEG is not part of this β€” use createImageBitmap in the browser, or any decoder in Deno.
  • Compositing is yours. The pipeline returns the matte, not a cut-out: whether alpha goes into an RGBA buffer, gets composited over a flat colour, or is fed to a colour decontamination pass is a decision this repository should not make for you.
  • Not readable by transformers (it's a different container with an embedded graph); the reader is a pipeline that implements birefnet/1.
  • Exporter used for the conversion: karume/0.10.0. The distribution manifest is karume.json (karume/4).

Base weights and attribution

  • Weights: egeorcun/lucida, licensed mit (as of retrieval) β€” a verbatim copy of the license, carrying the copyright notices that apply to this repository, is in LICENSE.md.
  • Fine-tune of: ZhengPeng7/BiRefNet_HR (mit) β€” architecture and initial weights; the upstream copyright notice is preserved.
  • Illustration training data includes ToonOut (CC-BY-4.0); other sets it draws on (P3M-10k, COD10K, DIS5K) are distributed for research purposes β€” check them against your own use case.
  • Not included: lucida-m35-comfy.safetensors. That experimental variant has the Normalize step folded into its first convolution (it expects raw [0, 1] pixels), so the preprocessing this pipeline applies would be counted twice, and upstream ships it to run inside a larger ComfyUI pipeline rather than bare.
  • Architecture: BiRefNet (arxiv.org/abs/2401.03407).
  • Changes made here (also listed in NOTICE.md): conversion into the Karume container format. No retraining, no fine-tuning and no quantization β€” the weights are the source checkpoint's own f32 values. The graph is the upstream forward with layout-only rewrites (windowing, the shifted-window roll, spatial padding and the patch merges were folded into equivalent operations β€” bit-exact), plus three rewrites that are equivalent up to floating-point rounding: inference-time BatchNorm2d became a per-channel affine, the ASPP image-level pooling became a two-stage sum, and the decoder tail's 1Γ—1 convolution was swapped with the bilinear upsample it used to follow (both are linear, so they commute β€” this removes two full-resolution intermediates).

Models

Model Pipeline Quants Default quant
1024 (default) birefnet/1 f32 f32
2048 birefnet/1 f32 f32

model selects one of these; omitted, it is 1024. quant defaults to that model's own default quant.

Usage

import { BirefnetPipeline } from "jsr:@karume/models";

await using pipeline = await BirefnetPipeline.fromPretrained({
  repo: "hdae/karume-lucida",
  // Pin a commit for reproducible builds β€” without it you track `main`, and a future
  // repo update (renamed files, new manifest format) may break your app.
  // Copy the full hash from this repo's "Files and versions" tab:
  // revision: "<full commit sha>",
}, {
  // model: "1024", // default β€” available: 1024 / 2048
  // quant: "f32", // default β€” available: f32
});

// RGB8, row-major, 3 bytes per pixel. Decoding is the caller's job.
const image = { data: pixels, width, height };
const matte = await pipeline.segment(image);

// matte.data is one alpha byte per pixel, same width/height as the input.
// Straight alpha into an RGBA buffer (canvas, ImageData, an RGBA encoder):
const rgba = new Uint8Array(matte.width * matte.height * 4);
for (let i = 0; i < matte.data.length; i += 1) {
  for (let c = 0; c < 3; c += 1) rgba[i * 4 + c] = image.data[i * 3 + c];
  rgba[i * 4 + 3] = matte.data[i];
}

segment() keeps one GPU session alive for the lifetime of the pipeline, so processing many images uploads the weights once; concurrent calls are queued rather than run side by side. Weights are fetched once and cached (verified against karume.json's size / sha256).

Model: 1024

Quants

Quant What it is Download Weights Compute
f32 (default) β€” 920 MiB matte = f32 β€”

If no quant is given, it runs as f32 (this model's recommended default). Per-file size and sha256 live in karume.json β€” verify against that at the fetch layer. Dtype labels use the runtime's storage dtype vocabulary (f16 / i8 / i4), not the fp16 spelling common elsewhere in the ecosystem.

Input and output

The resize target is the exported graph's own input shape; the normalization constants are the upstream preprocessor's (ImageNet statistics).

  • input: RGB8 pixels, resized to 1024 Γ— 1024 (bilinear, antialiased). The aspect ratio is not preserved β€” there is no crop and no padding, matching the upstream processor.
  • normalization: (pixel / 255 - mean) / std, mean 0.485 / 0.456 / 0.406, std 0.229 / 0.224 / 0.225
  • output: one alpha byte per pixel at the size of the image you passed in (the graph itself emits pre-sigmoid logits; the sigmoid and the resize back happen on the host).
  • required GPU memory: about 1.7 GiB allocated in total β€” the weights listed above, resident, plus 749 MiB for the intermediate tensors β€” and the largest single storage buffer is 256 MiB (measured 2026-09-05 on an RTX 3080 Ti); one image takes about 1.8 s. WebGPU's default maxStorageBufferBindingSize is 128 MiB, so this is in practice a desktop-class GPU requirement. karume.json does not declare it: the declared limits cover the resident weights and state, not the intermediate tensors a run allocates.

Model: 2048

Quants

Quant What it is Download Weights Compute
f32 (default) β€” 1.09 GiB matte = f32 β€”

If no quant is given, it runs as f32 (this model's recommended default). Per-file size and sha256 live in karume.json β€” verify against that at the fetch layer. Dtype labels use the runtime's storage dtype vocabulary (f16 / i8 / i4), not the fp16 spelling common elsewhere in the ecosystem.

Input and output

The resize target is the exported graph's own input shape; the normalization constants are the upstream preprocessor's (ImageNet statistics).

  • input: RGB8 pixels, resized to 2048 Γ— 2048 (bilinear, antialiased). The aspect ratio is not preserved β€” there is no crop and no padding, matching the upstream processor.
  • normalization: (pixel / 255 - mean) / std, mean 0.485 / 0.456 / 0.406, std 0.229 / 0.224 / 0.225
  • output: one alpha byte per pixel at the size of the image you passed in (the graph itself emits pre-sigmoid logits; the sigmoid and the resize back happen on the host).
  • required GPU memory: about 4.1 GiB allocated in total β€” the weights listed above, resident, plus 2,948 MiB for the intermediate tensors β€” and the attention score buffer alone is 878 MiB (measured 2026-09-05 on an RTX 3080 Ti); one image takes 7.5 – 8.6 s. WebGPU's default maxStorageBufferBindingSize is 128 MiB, so this is in practice a desktop-class GPU requirement. karume.json does not declare it: the declared limits cover the resident weights and state, not the intermediate tensors a run allocates.
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Model tree for hdae/karume-lucida

Finetuned
egeorcun/lucida
Finetuned
(1)
this model

Paper for hdae/karume-lucida