fomext commited on
Commit
bd7fedf
·
verified ·
1 Parent(s): 8926ae0

Upload 3 files

Browse files
Files changed (3) hide show
  1. Dockerfile +17 -0
  2. app.py +67 -0
  3. requirements.txt +7 -0
Dockerfile ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10-slim
2
+
3
+ WORKDIR /app
4
+
5
+ # System deps
6
+ RUN apt-get update && apt-get install -y \
7
+ git \
8
+ && rm -rf /var/lib/apt/lists/*
9
+
10
+ COPY requirements.txt .
11
+ RUN pip install --no-cache-dir -r requirements.txt
12
+
13
+ COPY app.py .
14
+
15
+ EXPOSE 7860
16
+
17
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
app.py ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ from pydantic import BaseModel
3
+ from transformers import AutoTokenizer, AutoModelForCausalLM
4
+ import torch
5
+
6
+ MODEL_ID = "meta-llama/Meta-Llama-3.1-8B-Instruct"
7
+
8
+ app = FastAPI(title="Artist Description Generator")
9
+
10
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
11
+ model = AutoModelForCausalLM.from_pretrained(
12
+ MODEL_ID,
13
+ device_map="auto",
14
+ torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
15
+ load_in_4bit=torch.cuda.is_available()
16
+ )
17
+
18
+ class ArtistInput(BaseModel):
19
+ artist_name: str
20
+ country: str | None = None
21
+ genres: list[str] = []
22
+ top_tracks: list[str] = []
23
+ metrics: dict = {}
24
+
25
+ def build_prompt(data: ArtistInput) -> str:
26
+ return f"""
27
+ You are writing a factual artist description for a music analytics platform.
28
+
29
+ Rules:
30
+ - Use ONLY the provided data
31
+ - Do NOT invent awards, numbers, or events
32
+ - If data is missing, omit it
33
+ - Keep it concise and neutral
34
+ - 3–5 sentences maximum
35
+
36
+ Artist name: {data.artist_name}
37
+ Country: {data.country}
38
+ Genres: {", ".join(data.genres)}
39
+ Top tracks: {", ".join(data.top_tracks)}
40
+ Metrics: {data.metrics}
41
+
42
+ Artist description:
43
+ """.strip()
44
+
45
+ @app.post("/generate")
46
+ def generate_description(data: ArtistInput):
47
+ prompt = build_prompt(data)
48
+
49
+ inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
50
+
51
+ with torch.no_grad():
52
+ output = model.generate(
53
+ **inputs,
54
+ max_new_tokens=180,
55
+ temperature=0.3,
56
+ top_p=0.9,
57
+ do_sample=True
58
+ )
59
+
60
+ text = tokenizer.decode(output[0], skip_special_tokens=True)
61
+
62
+ description = text.split("Artist description:")[-1].strip()
63
+
64
+ return {
65
+ "artist": data.artist_name,
66
+ "description": description
67
+ }
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ transformers
4
+ torch
5
+ accelerate
6
+ bitsandbytes
7
+ pydantic