Andhs commited on
Commit
6282d7b
·
verified ·
1 Parent(s): ee525c1

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +14 -26
app.py CHANGED
@@ -14,13 +14,6 @@ from threading import Thread
14
  MODEL_NAME = os.getenv("MODEL_NAME", "dllm-hub/Qwen3-0.6B-diffusion-bd3lm-v0.1")
15
  IS_DIFFUSION = "diffusion" in MODEL_NAME.lower()
16
 
17
- # CPU optimizations: tune threads and disable denormals before any torch work
18
- if not torch.cuda.is_available():
19
- torch.set_num_threads(os.cpu_count() or 4)
20
- torch.set_num_interop_threads(1)
21
- torch.set_flush_denormal(True)
22
- print(f"CPU mode: using {torch.get_num_threads()} threads, interop=1, flush_denormal=True")
23
-
24
  # Dynamic initialization layer targeting Diffusion Language Models
25
  if IS_DIFFUSION:
26
  try:
@@ -86,11 +79,13 @@ def clone_past_key_values(pkv):
86
  """Clone KV-cache. Fast path for tuples and Cache objects; falls back to deepcopy."""
87
  if pkv is None:
88
  return None
 
89
  if isinstance(pkv, tuple):
90
  return tuple(
91
  (k.clone() if k is not None else None, v.clone() if v is not None else None)
92
  for k, v in pkv
93
  )
 
94
  if hasattr(pkv, 'key_cache') and hasattr(pkv, 'value_cache'):
95
  try:
96
  new_cache = pkv.__class__()
@@ -102,6 +97,7 @@ def clone_past_key_values(pkv):
102
  return new_cache
103
  except Exception:
104
  pass
 
105
  return copy.deepcopy(pkv)
106
 
107
 
@@ -326,39 +322,33 @@ def generate_stream(model, tokenizer, prompt, steps=128, max_new_tokens=128, blo
326
  def load_model():
327
  global model, tokenizer, device
328
  device = "cuda" if torch.cuda.is_available() else "cpu"
329
- # Use float32 on CPU (bfloat16 is very slow on CPU); keep bfloat16 on GPU
330
- dtype = torch.bfloat16 if device == "cuda" else torch.float32
331
-
332
- print(f"Initializing {MODEL_NAME} on {device} with dtype={dtype}... (Diffusion Strategy Flag = {IS_DIFFUSION})")
333
-
334
  if IS_DIFFUSION:
335
  model = AutoModelForMaskedLM.from_pretrained(
336
  MODEL_NAME,
337
- torch_dtype=dtype,
338
  trust_remote_code=True
339
  ).to(device).eval()
340
  else:
341
  model = AutoModelForCausalLM.from_pretrained(
342
  MODEL_NAME,
343
- torch_dtype=dtype,
344
  trust_remote_code=False
345
  ).to(device).eval()
346
-
347
- # Compile model only on GPU causal models; skip on CPU and diffusion
348
- if device == "cuda" and not IS_DIFFUSION:
349
  try:
350
  model = torch.compile(model, mode="reduce-overhead", fullgraph=False)
351
  print("Model compiled with torch.compile.")
352
  except Exception as e:
353
  print(f"torch.compile skipped: {e}")
354
  else:
355
- print("torch.compile skipped (CPU or diffusion).")
356
-
357
  tokenizer = AutoTokenizer.from_pretrained(
358
  MODEL_NAME,
359
  trust_remote_code=IS_DIFFUSION
360
  )
361
- print("Model loaded into memory workspace.")
362
 
363
 
364
  @app.route('/health', methods=['GET'])
@@ -381,6 +371,7 @@ def generate_text():
381
  {"role": "system", "content": system_prompt},
382
  {"role": "user", "content": prompt}
383
  ]
 
384
  encoded = tokenizer.apply_chat_template(
385
  messages,
386
  add_generation_prompt=True,
@@ -408,8 +399,7 @@ def generate_text():
408
  max_new_tokens=max_new_tokens,
409
  temperature=temperature,
410
  do_sample=True if temperature > 0 else False,
411
- pad_token_id=tokenizer.eos_token_id,
412
- use_cache=True,
413
  )
414
  generated_ids = output_ids[0, input_ids.shape[-1]:]
415
  generated_text = tokenizer.decode(generated_ids, skip_special_tokens=True)
@@ -462,8 +452,7 @@ def generate_text_stream():
462
  output_ids = model.generate(
463
  input_ids, max_new_tokens=max_new_tokens, temperature=temperature,
464
  do_sample=True if temperature > 0 else False,
465
- pad_token_id=tokenizer.eos_token_id,
466
- use_cache=True,
467
  )
468
  generated_ids = output_ids[0, input_ids.shape[-1]:]
469
  generated_text = tokenizer.decode(generated_ids, skip_special_tokens=True)
@@ -516,7 +505,6 @@ def generate_text_sse():
516
  temperature=temperature,
517
  do_sample=True if temperature > 0 else False,
518
  pad_token_id=tokenizer.eos_token_id,
519
- use_cache=True,
520
  )
521
 
522
  def _generate():
@@ -528,7 +516,7 @@ def generate_text_sse():
528
 
529
  accumulated = []
530
  for text in streamer:
531
- if not text:
532
  continue
533
  accumulated.append(text)
534
  current = "".join(accumulated)
 
14
  MODEL_NAME = os.getenv("MODEL_NAME", "dllm-hub/Qwen3-0.6B-diffusion-bd3lm-v0.1")
15
  IS_DIFFUSION = "diffusion" in MODEL_NAME.lower()
16
 
 
 
 
 
 
 
 
17
  # Dynamic initialization layer targeting Diffusion Language Models
18
  if IS_DIFFUSION:
19
  try:
 
79
  """Clone KV-cache. Fast path for tuples and Cache objects; falls back to deepcopy."""
80
  if pkv is None:
81
  return None
82
+ # Fast path: legacy tuple format
83
  if isinstance(pkv, tuple):
84
  return tuple(
85
  (k.clone() if k is not None else None, v.clone() if v is not None else None)
86
  for k, v in pkv
87
  )
88
+ # Fast path: transformers Cache objects (DynamicCache, etc.)
89
  if hasattr(pkv, 'key_cache') and hasattr(pkv, 'value_cache'):
90
  try:
91
  new_cache = pkv.__class__()
 
97
  return new_cache
98
  except Exception:
99
  pass
100
+ # Fallback
101
  return copy.deepcopy(pkv)
102
 
103
 
 
322
  def load_model():
323
  global model, tokenizer, device
324
  device = "cuda" if torch.cuda.is_available() else "cpu"
325
+ print(f"Initializing {MODEL_NAME} on {device}... (Diffusion Strategy Flag = {IS_DIFFUSION})")
 
 
 
 
326
  if IS_DIFFUSION:
327
  model = AutoModelForMaskedLM.from_pretrained(
328
  MODEL_NAME,
329
+ torch_dtype=torch.bfloat16,
330
  trust_remote_code=True
331
  ).to(device).eval()
332
  else:
333
  model = AutoModelForCausalLM.from_pretrained(
334
  MODEL_NAME,
335
+ torch_dtype=torch.bfloat16,
336
  trust_remote_code=False
337
  ).to(device).eval()
338
+ # Compile model for faster inference — ONLY for standard causal models
339
+ if not IS_DIFFUSION:
 
340
  try:
341
  model = torch.compile(model, mode="reduce-overhead", fullgraph=False)
342
  print("Model compiled with torch.compile.")
343
  except Exception as e:
344
  print(f"torch.compile skipped: {e}")
345
  else:
346
+ print("Diffusion model loaded without torch.compile (custom FX code incompatible with Dynamo).")
 
347
  tokenizer = AutoTokenizer.from_pretrained(
348
  MODEL_NAME,
349
  trust_remote_code=IS_DIFFUSION
350
  )
351
+ print("Model compilation completed and loaded into memory workspace.")
352
 
353
 
354
  @app.route('/health', methods=['GET'])
 
371
  {"role": "system", "content": system_prompt},
372
  {"role": "user", "content": prompt}
373
  ]
374
+ # enable_thinking=False for ALL routes to prevent Qwen3 from leaking internal monologue
375
  encoded = tokenizer.apply_chat_template(
376
  messages,
377
  add_generation_prompt=True,
 
399
  max_new_tokens=max_new_tokens,
400
  temperature=temperature,
401
  do_sample=True if temperature > 0 else False,
402
+ pad_token_id=tokenizer.eos_token_id
 
403
  )
404
  generated_ids = output_ids[0, input_ids.shape[-1]:]
405
  generated_text = tokenizer.decode(generated_ids, skip_special_tokens=True)
 
452
  output_ids = model.generate(
453
  input_ids, max_new_tokens=max_new_tokens, temperature=temperature,
454
  do_sample=True if temperature > 0 else False,
455
+ pad_token_id=tokenizer.eos_token_id
 
456
  )
457
  generated_ids = output_ids[0, input_ids.shape[-1]:]
458
  generated_text = tokenizer.decode(generated_ids, skip_special_tokens=True)
 
505
  temperature=temperature,
506
  do_sample=True if temperature > 0 else False,
507
  pad_token_id=tokenizer.eos_token_id,
 
508
  )
509
 
510
  def _generate():
 
516
 
517
  accumulated = []
518
  for text in streamer:
519
+ if not text: # skip empty chunks
520
  continue
521
  accumulated.append(text)
522
  current = "".join(accumulated)