# Image classification (/ai-capabilities/image-classification)



## Overview

Image classification uses a **GGML** inference engine ([`@qvac/classification-ggml`](https://github.com/tetherto/qvac/tree/main/packages/classification-ggml)). Load a model using `modelType: "classification"`. The addon ships with a bundled MobileNetV3-Small that classifies images into three labels — `"food"`, `"report"`, and `"other"` — so no `modelSrc` and no model download are required out of the box. Custom GGUF classifiers are supported by passing your own `modelSrc`.

Provide an image to `classify()` as a `Uint8Array` of either:

* an encoded **JPEG or PNG** buffer; or
* **raw RGB** bytes, alongside `width`, `height`, and `channels: 3`.

`classify()` returns `ClassificationResult[]` — an array of `{ label, confidence }` entries sorted by confidence in descending order. Use `topK` to limit the number of results returned, either as a load-time default (`modelConfig.topK`) or as a per-call override.

## Functions

Use the following sequence of function calls:

1. [`loadModel()`](/reference/api#loadmodel)
2. [`classify()`](/reference/api#classify)
3. [`unloadModel()`](/reference/api#unloadmodel)

For how to use each function, see [SDK — API reference](/reference/api/).

## Models

Supported model families and their file layouts:

* **MobileNetV3-Small**: single all-in-one `*.gguf` file — the base model or any fine-tune of the same architecture (converted to GGUF). Fine-tunes may define their own classes and labels; the label set is sourced from the GGUF metadata.

For models available as constants, see [SDK — Models](/introduction#models).

<Callout type="info">
  **Default model:** alternatively, you can load no model at all. In that case the base **MobileNetV3-Small** classifier is loaded automatically — no `modelSrc` and no download required. It emits the following fixed labels: `"food"`, `"report"`, and `"other"`.
</Callout>

## Example

The following script classifies a JPEG image using the bundled MobileNetV3-Small model:

<Tabs>
  <Tab value="js" label="JavaScript" default>
    <WrapCode>
      ```js file=<rootDir>/packages/sdk/dist/examples/classification/classify-image.js title="classify-image.js" lineNumbers
      import fs from "fs";
      import { startQVACProvider, stopQVACProvider, loadModel, classify, unloadModel } from "@qvac/sdk";
      /**
       * Classify an image using the bundled MobileNetV3-Small model.
       *
       * The bundled model produces three classes: "food", "report", "other".
       * No modelSrc is needed — the model ships inside @qvac/classification-ggml.
       */
      async function main() {
          await startQVACProvider({});
          const modelId = await loadModel({
              modelType: "ggml-classification",
          });
          const image = fs.readFileSync("image.jpg");
          const results = await classify({ modelId, image });
          console.log("Classification results:");
          for (const { label, confidence } of results) {
              console.log(`  ${label}: ${(confidence * 100).toFixed(1)}%`);
          }
          await unloadModel({ modelId });
          await stopQVACProvider();
      }
      main().catch(console.error);
      ```
    </WrapCode>
  </Tab>

  <Tab value="ts" label="TypeScript">
    <WrapCode>
      ```ts file=<rootDir>/packages/sdk/examples/classification/classify-image.ts title="classify-image.ts" lineNumbers
      import fs from "fs";
      import { startQVACProvider, stopQVACProvider, loadModel, classify, unloadModel } from "@qvac/sdk";

      /**
       * Classify an image using the bundled MobileNetV3-Small model.
       *
       * The bundled model produces three classes: "food", "report", "other".
       * No modelSrc is needed — the model ships inside @qvac/classification-ggml.
       */
      async function main() {
        await startQVACProvider({});

        const modelId = await loadModel({
          modelType: "ggml-classification",
        });

        const image = fs.readFileSync("image.jpg");
        const results = await classify({ modelId, image });

        console.log("Classification results:");
        for (const { label, confidence } of results) {
          console.log(`  ${label}: ${(confidence * 100).toFixed(1)}%`);
        }

        await unloadModel({ modelId });
        await stopQVACProvider();
      }

      main().catch(console.error);
      ```
    </WrapCode>
  </Tab>
</Tabs>

<Callout type="success">
  **Tip:** all examples throughout this documentation are self-contained and runnable. For instructions on how to run them, see [SDK quickstart](/quickstart).
</Callout>
