Skip to content

Commit 2858c2a

Browse files
committed
Added image generation functionality
1 parent 9d9c660 commit 2858c2a

File tree

3 files changed

+114
-12
lines changed

3 files changed

+114
-12
lines changed

README.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
# AI Function Agent
1+
# AI Function Agent (WIP!)
22

3-
A simple script using Qwen-Agent to access a locally running model for function/tool calling.
3+
A simple script using Qwen-Agent to for LLM inference based python function calling
4+
5+
- Chat with your own local or remote AI assistant that can run python code implicitly
6+
- Build an AI mediated automation ecosystem tailored to your workload
7+
- Generate images using the included image generation tool and the [Lumina-Image-2.0](https://huggingface.co/Alpha-VLLM/Lumina-Image-2.0) model!
48

59
## Setup
610

@@ -15,7 +19,7 @@ A simple script using Qwen-Agent to access a locally running model for function/
1519
- `python -m venv aiAgentVenv`
1620
- Once created, it can be activated with:
1721
- `./aiAgentVenv/Scripts/activate`
18-
- If you want to run the main LLM locally, we recommend using [llamma.cpp](https://github.com/ggerganov/llama.cpp/releases)'s OpenAI API [compatable server](https://github.com/ggerganov/llama.cpp/blob/master/examples/server/README.md).
22+
- If you want to run the main LLM locally, we recommend using [llama.cpp](https://github.com/ggerganov/llama.cpp/releases)'s OpenAI API [compatable server](https://github.com/ggerganov/llama.cpp/blob/master/examples/server/README.md).
1923

2024

2125
### Modules
@@ -24,14 +28,15 @@ Installing modules in the correct order helps make sure everything installs with
2428

2529
1. [Install torch, torchvision, and torchaudio](https://pytorch.org/get-started/locally/) with CUDA/ROCM if possible
2630
2. `pip install duckduckgo-search qwen-agent transformers usearch`
31+
3. `pip install git+https://github.com/zhuole1025/diffusers.git@lumina2` (fork of diffusers with new lumina2 image pipeline)
2732

2833
## Usage
2934

3035
### Backend Configuration
3136

3237
You'll need to open and edit the [config.json](/config.json) file locally to have the correct URL and API key for your tool calling model. This can be a locally hosted model, or a remote model so long as the backend uses an OpenAI API compatable server.
3338

34-
As stated above, for local use we recommend using [llamma.cpp](https://github.com/ggerganov/llama.cpp/releases)'s OpenAI API [compatable server](https://github.com/ggerganov/llama.cpp/blob/master/examples/server/README.md).
39+
As stated above, for local use we recommend using [llama.cpp](https://github.com/ggerganov/llama.cpp/releases)'s OpenAI API [compatable server](https://github.com/ggerganov/llama.cpp/blob/master/examples/server/README.md).
3540

3641
### Running the Script
3742

@@ -47,7 +52,7 @@ There are a few commands you can use in the prompt, type `help` to list them all
4752

4853
### Available tools
4954

50-
Pre-made tools exist and can be found in the [functions](/functions) folder of the repo
55+
Pre-made tools exist and can be found in the [functions](/functions) folder of the repo.
5156

5257
### Making your own tooling
5358

functions/system/image_gen.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import os
2+
import random
3+
import time
4+
5+
import numpy as np
6+
import torch
7+
from diffusers import Lumina2Text2ImgPipeline
8+
9+
10+
# Where to load the model
11+
if torch.cuda.is_available():
12+
device = "cuda"
13+
torch_dtype = torch.bfloat16
14+
else:
15+
device = "cpu"
16+
torch_dtype = torch.float32
17+
18+
19+
def gen_image(prompt: str, width: int = 512, height: int = 512, open: bool = True) -> str:
20+
21+
# Clamp H and W to 1024 (subject to change)
22+
height = min(height, 1024)
23+
width = min(width, 1024)
24+
print("Loading image generation model...")
25+
pipe = Lumina2Text2ImgPipeline.from_pretrained(
26+
"Alpha-VLLM/Lumina-Image-2.0", torch_dtype=torch_dtype
27+
)
28+
pipe.to(device, torch_dtype)
29+
30+
# Optimizations
31+
pipe.enable_vae_slicing()
32+
pipe.enable_vae_tiling()
33+
#pipe.enable_model_cpu_offload()
34+
35+
# Randomize the seed
36+
MAX_SEED = np.iinfo(np.int32).max
37+
seed = random.randint(0, MAX_SEED)
38+
39+
# Generate the image
40+
image = pipe(
41+
prompt,
42+
height=height,
43+
width=width,
44+
guidance_scale=4.0,
45+
num_inference_steps=30,
46+
cfg_trunc_ratio=0.25,
47+
cfg_normalization=True,
48+
generator=torch.Generator().manual_seed(seed),
49+
).images[0]
50+
51+
os.makedirs("images", exist_ok=True)
52+
f_name = f"images/image_{int(time.time())}.png"
53+
54+
image.save(f_name)
55+
56+
if open:
57+
image.show()
58+
return f"Image created at path: {f_name}"
59+
60+
61+
function = gen_image
62+
function_spec = {
63+
"type": "function",
64+
"function": {
65+
"name": "gen_image",
66+
"description": "Generates an image when requested by the user. If they did not specify a prompt, you MUST ask them for one before using this.",
67+
"parameters": {
68+
"type": "object",
69+
"properties": {
70+
"prompt": {
71+
"type": "string",
72+
"description": "The user's prompt for the image generation model",
73+
},
74+
"width": {
75+
"type": "int",
76+
"description": "The user defined width of the image (or 512 if not specified)",
77+
},
78+
"height": {
79+
"type": "int",
80+
"description": "The user defined height of the image (or 512 if not specified)",
81+
}
82+
},
83+
"required": ["prompt"],
84+
},
85+
},
86+
}
87+
88+
89+
if __name__ == "__main__":
90+
while True:
91+
prompt = input("Image Generation Prompt: ")
92+
gen_image(prompt)

tool_calling.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,9 @@ def print_help():
164164
print("clear")
165165
print(" Clears the console and the chat history for a new convo")
166166
print("load")
167-
print(" Load's the functions in the user folder. (can be enabled by default in the config)")
167+
print(
168+
" Load's the functions in the user folder. (can be enabled by default in the config)"
169+
)
168170

169171

170172
def main():
@@ -176,14 +178,17 @@ def main():
176178
}
177179
)
178180

181+
system_prompt = inspect.cleandoc(f"""
182+
You are JARVIS, a helpful and witty assistant.
183+
You help a user with their tasks by using any of the functions available to you and your replies should always aim to be short but informative.
184+
When a user refers to themselves in a prompt to create or recall a memory in the first person, change it to refer to 'The User'.
185+
If you cannot answer a prompt based on information you have available, use your tools to find more information.
186+
The current date is {datetime.today().strftime('%Y-%m-%d %H:%M:%S')}
187+
""")
188+
179189
system_message = {
180190
"role": "system",
181-
"content": f"""You are JARVIS, a helpful and witty assistant.
182-
You help a user with their tasks by using any of the functions available to you and your replies should always aim to be short but informative.
183-
When a user refers to themselves in a prompt to create or recall a memory in the first person, change it to refer to 'The User'.
184-
If you cannot answer a prompt based on information you have available, use your tools to find more information.
185-
The current date is {datetime.today().strftime('%Y-%m-%d %H:%M:%S')}
186-
""",
191+
"content": system_prompt,
187192
}
188193

189194
print("Type 'help' for chat commands")

0 commit comments

Comments
 (0)