Compare commits

...

1 Commits

Author SHA1 Message Date
Matt Williams
18b2015499 add example that applies llava to image management
Signed-off-by: Matt Williams <m@technovangelist.com>
2024-01-05 09:21:38 -08:00
4 changed files with 89 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -0,0 +1,18 @@
{
"name": "typescript-airenamer",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "tsx renamer.ts",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"tsx": "^4.7.0"
},
"devDependencies": {
"@types/node": "^20.10.6"
}
}

View File

@ -0,0 +1,29 @@
# Renaming Files with AI
![airenamer 2024-01-05 09_09_08](https://github.com/jmorganca/ollama/assets/633681/b98df1c8-61a7-4dff-aeb7-b04e034dced0)
This example applies the benefits of the llava models to managing images. It will find any images in your current directory, generate keywords for the image, and then copy the file to a new name based on the keywords.
## Running the example
1. Clone this repo and navigate to the `examples/typescript-airenamer` directory.
2. Install the dependencies with `npm install`.
3. Run `npm run start`.
## Review the Code
The main part of the code is in the `getkeywords` function. It calls the `/api/generate` endpoint passing in the body:
```json
{
"model": "llava:13b-v1.5-q5_K_M",
"prompt": `Describe the image as a collection of keywords. Output in JSON format. Use the following schema: { filename: string, keywords: string[] }`,
"format": "json",
"images": [image],
"stream": false
}
```
This demonstrates how to use images as well as `format: json` to allow calling another function. The images key takes an array of base64 encoded images. And `format: json` tells the model to output JSON instead of regular text. When using `format: json`, it's important to also say that you expect the output to be JSON in the prompt. Adding the expected schema to the prompt also helps the model understand what you're looking for.
The `main` function calls getkeywords passing it the base64 encoded image. Then it parses the JSON output, formats the keywords into a string, and copies the file to the new name.

View File

@ -0,0 +1,42 @@
import fs from 'fs';
export async function getkeywords(image: string): Promise<string[]> {
const body = {
"model": "llava:13b-v1.5-q5_K_M",
"prompt": `Describe the image as a collection of keywords. Output in JSON format. Use the following schema: { filename: string, keywords: string[] }`,
"format": "json",
"images": [image],
"stream": false
};
const response = await fetch("http://localhost:11434/api/generate", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
const json = await response.json();
const keywords = JSON.parse(json.response);
return keywords?.keywords || [];
}
async function main() {
for (const file of fs.readdirSync(".")) {
if (file.endsWith(".jpg") || file.endsWith(".png")) {
const currentpath = __dirname;
const b64 = fs.readFileSync(`${currentpath}/${file}`, { encoding: 'base64' });
const keywords = await getkeywords(b64.toString());
const fileparts = keywords.map(k => k.replace(/ /g, "_"));
const fileext = file.split(".").pop();
const newfilename = fileparts.join("-") + "." + fileext;
fs.copyFileSync(`${currentpath}/${file}`, `${currentpath}/${newfilename}`);
console.log(`Copied ${file} to ${newfilename}`);
}
}
}
main();