-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.js
More file actions
152 lines (139 loc) · 4.47 KB
/
Copy pathserver.js
File metadata and controls
152 lines (139 loc) · 4.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
require("dotenv").config();
const express = require("express");
const cors = require("cors");
const axios = require("axios");
const app = express();
const port = 3000;
app.use(express.json());
//app.use(cors());
app.use(
cors({
origin: "https://pgm-llm-project.github.io",
methods: ["POST"],
allowedHeaders: ["Content-Type"],
})
);
app.post("/", async (req, res) => {
const { TOGETHER_API_KEY, GROQ_API_KEY } = process.env;
// const TOGETHER_URL = "https://api.together.xyz/v1/chat/completions";
const TOGETHER_BASE_URL = "https://api.together.xyz";
const GROQ_URL = "https://api.groq.com/openai/v1/chat/completions";
const TURBO_MODEL = "meta-llama/Llama-3.3-70B-Instruct-Turbo-Free";
const FLUX_MODEL = "black-forest-labs/FLUX.1-schnell-Free";
const MIXTRAL_MODEL = "mixtral-8x7b-32768";
const DEEPSEEK_MODEL = "deepseek-ai/DeepSeek-R1-Distill-Llama-70B-free";
async function callAI({
url,
model,
text,
textForImage,
apiKey,
jsonMode = false,
max_tokens,
}) {
// const payload = {
// model,
// messages: [
// {
// role: "user",
// content: text,
// },
// ],
// };
const payload = {
model,
};
if (max_tokens) {
payload.max_tokens = max_tokens;
}
if (text) {
payload.messages = [
{
role: "user",
content: text,
},
];
}
if (textForImage) {
payload.prompt = textForImage;
}
if (jsonMode) {
payload.response_format = { type: "json_object" };
}
const response = await axios.post(url, payload, {
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
});
return response.data;
}
// 1. 텍스트를 받아옴
const { text } = req.body;
// 2-1. 이미지를 생성하는 프롬프트
// llama-3-3-70b-free (together) -> 속도 측면
const prompt = await callAI({
url: `${TOGETHER_BASE_URL}/v1/chat/completions`,
apiKey: TOGETHER_API_KEY,
model: TURBO_MODEL,
// text,
text: `${text}를 바탕으로 맛집 추천에 어울리는 AI 이미지 생성을 위한 200자 이내의 영어 프롬프트를 작성해줘`,
}).then((res) => res.choices[0].message.content);
// 2-2. 그거에서 프롬프트만 JSON으로 추출
// mixtral-8x7b-32768 (groq)
const promptJSON = await callAI({
url: GROQ_URL,
apiKey: GROQ_API_KEY,
model: MIXTRAL_MODEL,
// text,
text: `${prompt}에서 AI 이미지 생성을 위해 작성된 200자 이내의 영어 프롬프트를 JSON Object로 prompt라는 key로 JSON string으로 ouput해줘`,
jsonMode: true,
}).then((res) => JSON.parse(res.choices[0].message.content).prompt);
// 2-3. 그걸로 이미지를 생성
// black-forest-labs/FLUX.1-schnell-Free (together)
const image = await callAI({
url: `${TOGETHER_BASE_URL}/v1/images/generations`,
apiKey: TOGETHER_API_KEY,
model: FLUX_MODEL,
// text,
text: promptJSON,
}).then((res) => res.data[0].url);
// 3-1. 설명을 생성하는 프롬프트
// llama-3-3-70b-free (together)
const prompt2 = await callAI({
url: `${TOGETHER_BASE_URL}/v1/chat/completions`,
apiKey: TOGETHER_API_KEY,
model: TURBO_MODEL,
// text,
text: `${text}를 바탕으로 맛집 추천에 어울리는 설명 생성을 위한 200자 이내의 한글 프롬프트를 작성해줘`,
}).then((res) => res.choices[0].message.content);
// 3-2. 그거에서 프롬프트만 추출
// mixtral-8x7b-32768 (groq)
const promptJSON2 = await callAI({
url: GROQ_URL,
apiKey: GROQ_API_KEY,
model: MIXTRAL_MODEL,
// text,
text: `${prompt2}에서 reasoning을 위해 작성된 200자 이내의 한글 프롬프트를 JSON Object로 prompt라는 key로 JSON string으로 ouput해줘`,
jsonMode: true,
}).then((res) => JSON.parse(res.choices[0].message.content).prompt);
// 3-3. 그걸로 thinking 사용해서 설명을 작성
// DeepSeek-R1-Distill-Llama-70B-free (together)
const desc = await callAI({
url: `${TOGETHER_BASE_URL}/v1/chat/completions`,
apiKey: TOGETHER_API_KEY,
model: DEEPSEEK_MODEL,
text: promptJSON2,
max_tokens: 2048,
}).then((res) => res.choices[0].message.content.split("</think>")[1]);
// desc = JSON.stringify(prompt);
// console.log(image);
// 4. 그 결과를 { image: _, desc: _ }
res.json({
image,
desc,
});
});
app.listen(port, () => {
console.log(`app listening on port ${port}`);
});