khushalcodiste commited on
Commit
debd1ce
·
1 Parent(s): 74139b5

fix: added

Browse files
Files changed (1) hide show
  1. server.js +109 -13
server.js CHANGED
@@ -6,6 +6,7 @@ import {
6
  Qwen3_5ForConditionalGeneration,
7
  RawImage,
8
  } from "@huggingface/transformers";
 
9
 
10
  const app = express();
11
  const upload = multer({ storage: multer.memoryStorage() });
@@ -16,8 +17,24 @@ let model = null;
16
  let processor = null;
17
  let inferenceQueue = Promise.resolve();
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  async function loadModel() {
20
- console.log(`Loading model ${MODEL_ID}...`);
 
21
  processor = await AutoProcessor.from_pretrained(MODEL_ID);
22
  model = await Qwen3_5ForConditionalGeneration.from_pretrained(MODEL_ID, {
23
  dtype: {
@@ -26,7 +43,10 @@ async function loadModel() {
26
  decoder_model_merged: "q4",
27
  },
28
  });
29
- console.log("Model loaded successfully.");
 
 
 
30
  }
31
 
32
  async function runInference(imageBuffer, prompt, maxTokens) {
@@ -144,57 +164,133 @@ const swaggerDoc = {
144
 
145
  app.use("/docs", swaggerUi.serve, swaggerUi.setup(swaggerDoc));
146
 
147
- app.get("/", (_req, res) => {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
  res.json({ status: "ok", model: MODEL_ID });
149
  });
150
 
151
- app.get("/health", (_req, res) => {
 
 
 
 
152
  res.json({ status: "healthy", model_loaded: model !== null });
153
  });
154
 
155
  app.post("/inference", upload.single("file"), async (req, res) => {
 
 
 
 
 
 
 
 
 
 
156
  if (!model || !processor) {
 
157
  return res.status(503).json({ detail: "Model not loaded yet." });
158
  }
159
  if (!req.file) {
 
 
 
 
160
  return res.status(400).json({ detail: "No image file provided." });
161
  }
162
 
163
- const prompt = req.body.prompt || "Describe this image in detail.";
164
- const maxTokens = parseInt(req.body.max_tokens) || 256;
165
-
166
  try {
 
167
  const response = await queueInference(req.file.buffer, prompt, maxTokens);
 
 
 
 
 
168
  res.json({ response });
169
  } catch (err) {
170
- console.error(err);
 
 
 
 
171
  res.status(500).json({ detail: "Inference failed.", error: err.message });
172
  }
173
  });
174
 
175
  app.post("/inference/base64", express.urlencoded({ extended: true, limit: "50mb" }), async (req, res) => {
 
 
 
 
 
 
 
 
 
 
176
  if (!model || !processor) {
 
177
  return res.status(503).json({ detail: "Model not loaded yet." });
178
  }
179
  if (!req.body.image_base64) {
 
 
 
 
180
  return res.status(400).json({ detail: "No base64 image provided." });
181
  }
182
 
183
- const prompt = req.body.prompt || "Describe this image in detail.";
184
- const maxTokens = parseInt(req.body.max_tokens) || 256;
185
-
186
  try {
 
187
  const imageBuffer = Buffer.from(req.body.image_base64, "base64");
188
  const response = await queueInference(imageBuffer, prompt, maxTokens);
 
 
 
 
 
 
189
  res.json({ response });
190
  } catch (err) {
191
- console.error(err);
 
 
 
 
192
  res.status(500).json({ detail: "Inference failed.", error: err.message });
193
  }
194
  });
195
 
196
  loadModel().then(() => {
197
  app.listen(PORT, "0.0.0.0", () => {
198
- console.log(`Server running on http://0.0.0.0:${PORT}`);
 
 
 
 
199
  });
200
  });
 
6
  Qwen3_5ForConditionalGeneration,
7
  RawImage,
8
  } from "@huggingface/transformers";
9
+ import crypto from "crypto";
10
 
11
  const app = express();
12
  const upload = multer({ storage: multer.memoryStorage() });
 
17
  let processor = null;
18
  let inferenceQueue = Promise.resolve();
19
 
20
+ function log(level, event, meta = {}) {
21
+ const payload = {
22
+ ts: new Date().toISOString(),
23
+ level,
24
+ event,
25
+ ...meta,
26
+ };
27
+ const line = JSON.stringify(payload);
28
+ if (level === "error") {
29
+ console.error(line);
30
+ } else {
31
+ console.log(line);
32
+ }
33
+ }
34
+
35
  async function loadModel() {
36
+ const start = Date.now();
37
+ log("info", "model_load_started", { model_id: MODEL_ID });
38
  processor = await AutoProcessor.from_pretrained(MODEL_ID);
39
  model = await Qwen3_5ForConditionalGeneration.from_pretrained(MODEL_ID, {
40
  dtype: {
 
43
  decoder_model_merged: "q4",
44
  },
45
  });
46
+ log("info", "model_load_completed", {
47
+ model_id: MODEL_ID,
48
+ duration_ms: Date.now() - start,
49
+ });
50
  }
51
 
52
  async function runInference(imageBuffer, prompt, maxTokens) {
 
164
 
165
  app.use("/docs", swaggerUi.serve, swaggerUi.setup(swaggerDoc));
166
 
167
+ app.use((req, res, next) => {
168
+ const requestId = crypto.randomUUID();
169
+ const start = Date.now();
170
+ req.requestId = requestId;
171
+ log("info", "request_started", {
172
+ request_id: requestId,
173
+ method: req.method,
174
+ path: req.originalUrl,
175
+ ip: req.ip,
176
+ });
177
+ res.on("finish", () => {
178
+ log("info", "request_finished", {
179
+ request_id: requestId,
180
+ method: req.method,
181
+ path: req.originalUrl,
182
+ status_code: res.statusCode,
183
+ duration_ms: Date.now() - start,
184
+ });
185
+ });
186
+ next();
187
+ });
188
+
189
+ app.get("/", (req, res) => {
190
+ log("info", "root_status", { request_id: req.requestId });
191
  res.json({ status: "ok", model: MODEL_ID });
192
  });
193
 
194
+ app.get("/health", (req, res) => {
195
+ log("info", "health_checked", {
196
+ request_id: req.requestId,
197
+ model_loaded: model !== null && processor !== null,
198
+ });
199
  res.json({ status: "healthy", model_loaded: model !== null });
200
  });
201
 
202
  app.post("/inference", upload.single("file"), async (req, res) => {
203
+ const prompt = req.body.prompt || "Describe this image in detail.";
204
+ const maxTokens = parseInt(req.body.max_tokens) || 256;
205
+ log("info", "inference_request_received", {
206
+ request_id: req.requestId,
207
+ has_file: Boolean(req.file),
208
+ file_size_bytes: req.file?.size ?? 0,
209
+ prompt_chars: prompt.length,
210
+ max_tokens: maxTokens,
211
+ });
212
+
213
  if (!model || !processor) {
214
+ log("error", "inference_model_unavailable", { request_id: req.requestId });
215
  return res.status(503).json({ detail: "Model not loaded yet." });
216
  }
217
  if (!req.file) {
218
+ log("error", "inference_validation_failed", {
219
+ request_id: req.requestId,
220
+ reason: "missing_file",
221
+ });
222
  return res.status(400).json({ detail: "No image file provided." });
223
  }
224
 
 
 
 
225
  try {
226
+ const start = Date.now();
227
  const response = await queueInference(req.file.buffer, prompt, maxTokens);
228
+ log("info", "inference_completed", {
229
+ request_id: req.requestId,
230
+ duration_ms: Date.now() - start,
231
+ response_chars: response?.length ?? 0,
232
+ });
233
  res.json({ response });
234
  } catch (err) {
235
+ log("error", "inference_failed", {
236
+ request_id: req.requestId,
237
+ error: err.message,
238
+ stack: err.stack,
239
+ });
240
  res.status(500).json({ detail: "Inference failed.", error: err.message });
241
  }
242
  });
243
 
244
  app.post("/inference/base64", express.urlencoded({ extended: true, limit: "50mb" }), async (req, res) => {
245
+ const prompt = req.body.prompt || "Describe this image in detail.";
246
+ const maxTokens = parseInt(req.body.max_tokens) || 256;
247
+ log("info", "inference_base64_request_received", {
248
+ request_id: req.requestId,
249
+ has_image_base64: Boolean(req.body.image_base64),
250
+ image_base64_chars: req.body.image_base64?.length ?? 0,
251
+ prompt_chars: prompt.length,
252
+ max_tokens: maxTokens,
253
+ });
254
+
255
  if (!model || !processor) {
256
+ log("error", "inference_base64_model_unavailable", { request_id: req.requestId });
257
  return res.status(503).json({ detail: "Model not loaded yet." });
258
  }
259
  if (!req.body.image_base64) {
260
+ log("error", "inference_base64_validation_failed", {
261
+ request_id: req.requestId,
262
+ reason: "missing_image_base64",
263
+ });
264
  return res.status(400).json({ detail: "No base64 image provided." });
265
  }
266
 
 
 
 
267
  try {
268
+ const start = Date.now();
269
  const imageBuffer = Buffer.from(req.body.image_base64, "base64");
270
  const response = await queueInference(imageBuffer, prompt, maxTokens);
271
+ log("info", "inference_base64_completed", {
272
+ request_id: req.requestId,
273
+ duration_ms: Date.now() - start,
274
+ image_bytes: imageBuffer.length,
275
+ response_chars: response?.length ?? 0,
276
+ });
277
  res.json({ response });
278
  } catch (err) {
279
+ log("error", "inference_base64_failed", {
280
+ request_id: req.requestId,
281
+ error: err.message,
282
+ stack: err.stack,
283
+ });
284
  res.status(500).json({ detail: "Inference failed.", error: err.message });
285
  }
286
  });
287
 
288
  loadModel().then(() => {
289
  app.listen(PORT, "0.0.0.0", () => {
290
+ log("info", "server_started", {
291
+ host: "0.0.0.0",
292
+ port: PORT,
293
+ model_id: MODEL_ID,
294
+ });
295
  });
296
  });