drrobot9 commited on
Commit
9fc4da3
·
verified ·
1 Parent(s): 4f204ac

Initial commit: FastAPI + Vision + LLM integration

Browse files
Files changed (5) hide show
  1. Dockerfile +9 -0
  2. app/__init__.py +0 -0
  3. app/main.py +22 -0
  4. app/pipeline.py +62 -0
  5. app/requirements.txt +11 -0
Dockerfile ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10-slim
2
+
3
+ WORKDIR /app
4
+ COPY ./app /app
5
+
6
+ RUN pip install --no-cache-dir -r requirements.txt
7
+
8
+ EXPOSE 7860
9
+ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
app/__init__.py ADDED
File without changes
app/main.py ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, UploadFile, File, Form
2
+ from fastapi.responses import JSONResponse
3
+ from app.pipeline import plant_intelligence_pipeline
4
+
5
+ app = FastAPI(
6
+ title=" Plant Intelligence AI",
7
+ description="Hybrid Plant Identifier + Reasoning Assistant",
8
+ version="1.0.0",
9
+ )
10
+
11
+ @app.get("/")
12
+ def home():
13
+ return {"message": "Welcome to the Plant Intelligence AI "}
14
+
15
+ @app.post("/analyze")
16
+ async def analyze(file: UploadFile = File(...), query: str = Form("")):
17
+ try:
18
+ image_bytes = await file.read()
19
+ result = plant_intelligence_pipeline(image_bytes, user_query=query)
20
+ return JSONResponse(result)
21
+ except Exception as e:
22
+ return JSONResponse({"error": str(e)}, status_code=500)
app/pipeline.py ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from transformers import (
2
+ AutoModelForImageClassification,
3
+ AutoProcessor,
4
+ AutoModelForCausalLM,
5
+ AutoTokenizer
6
+ )
7
+ from PIL import Image
8
+ import torch
9
+
10
+
11
+
12
+ VISION_MODEL_NAME = "drrobot9/plant-super-identification-vit-finetuned"
13
+ TEXT_MODEL_NAME = "Qwen/Qwen3-4B-Instruct-2507"
14
+
15
+ device = "cuda" if torch.cuda.is_available() else "cpu"
16
+
17
+ # Load vision model
18
+ vision_model = AutoModelForImageClassification.from_pretrained(VISION_MODEL_NAME).to(device)
19
+ vision_processor = AutoProcessor.from_pretrained(VISION_MODEL_NAME)
20
+
21
+ # Load text model
22
+ text_model = AutoModelForCausalLM.from_pretrained(TEXT_MODEL_NAME, device_map="auto", torch_dtype=torch.float16)
23
+ tokenizer = AutoTokenizer.from_pretrained(TEXT_MODEL_NAME)
24
+
25
+
26
+ def identify_plant(image_bytes: bytes):
27
+ """Classify plant image and return label + confidence."""
28
+ image = Image.open(io.BytesIO(image_bytes)).convert("RGB")
29
+ inputs = vision_processor(images=image, return_tensors="pt").to(device)
30
+ outputs = vision_model(**inputs)
31
+ probs = torch.nn.functional.softmax(outputs.logits, dim=-1)
32
+ conf, pred_idx = torch.max(probs, dim=1)
33
+ label = vision_model.config.id2label[pred_idx.item()]
34
+ return label, float(conf.item())
35
+
36
+
37
+ def explain_plant(plant_name: str, confidence: float, extra_context: str = ""):
38
+ """Use Qwen to explain the plant in natural language."""
39
+ prompt = f"""
40
+ You are a knowledgeable botanist assistant.
41
+ The identified plant is **{plant_name}** (confidence {confidence:.2f}).
42
+
43
+ Provide detailed information about:
44
+ - Scientific name
45
+ - Origin and climate preferences
46
+ - Watering and sunlight needs
47
+ - Growth conditions
48
+ - Medicinal or cultural uses
49
+ - built by kelvin jackson when asked
50
+ - you know all plants in this world
51
+ {extra_context}
52
+ """
53
+ inputs = tokenizer(prompt, return_tensors="pt").to(text_model.device)
54
+ output = text_model.generate(**inputs, max_new_tokens=500, temperature=0.7, top_p=0.9)
55
+ return tokenizer.decode(output[0], skip_special_tokens=True)
56
+
57
+
58
+ def plant_intelligence_pipeline(image_bytes: bytes, user_query: str = ""):
59
+ """Full hybrid pipeline."""
60
+ name, conf = identify_plant(image_bytes)
61
+ description = explain_plant(name, conf, user_query)
62
+ return {"plant": name, "confidence": conf, "description": description}
app/requirements.txt ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ transformers
4
+ torch
5
+ pillow
6
+ huggingface-hub
7
+ accelerate
8
+ einops
9
+ tiktoken
10
+ sentencepiece
11
+