malvin noel commited on
Commit
449544a
Β·
1 Parent(s): 51bba63

change script

Browse files
Files changed (2) hide show
  1. app.py +37 -3
  2. scripts/generate_scripts.py +11 -16
app.py CHANGED
@@ -17,6 +17,16 @@ from scripts.generate_subtitles import (
17
  add_subtitles_to_video,
18
  )
19
 
 
 
 
 
 
 
 
 
 
 
20
  # ──────────────────────────────────────────────────────────────────────────────
21
  # Constants & utilities
22
  # ──────────────────────────────────────────────────────────────────────────────
@@ -28,6 +38,30 @@ ASSETS_DIRS = (
28
  "./assets/video_music",
29
  )
30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  for d in ASSETS_DIRS:
32
  os.makedirs(d, exist_ok=True)
33
 
@@ -69,10 +103,10 @@ def cb_generate_script(
69
  f"Instruction: {instruction.strip()}\n"
70
  f"πŸ”΄ Strict target duration: {target_duration}s β€” β‰ˆ {approx_words} words (must be respected)."
71
  )
72
- script = generate_script(prompt)
73
 
74
- title = generate_title(script)
75
- description = generate_description(script)
76
  return script, title, description, script # last return for state update
77
 
78
 
 
17
  add_subtitles_to_video,
18
  )
19
 
20
+ from __future__ import annotations
21
+ import os
22
+ from typing import List
23
+ import torch
24
+ from transformers import (
25
+ AutoTokenizer,
26
+ AutoModelForCausalLM,
27
+ BitsAndBytesConfig,
28
+ )
29
+
30
  # ──────────────────────────────────────────────────────────────────────────────
31
  # Constants & utilities
32
  # ──────────────────────────────────────────────────────────────────────────────
 
38
  "./assets/video_music",
39
  )
40
 
41
+
42
+ # ────────────────────────────────────────────────────────
43
+ # CONFIGURATION
44
+ # ────────────────────────────────────────────────────────
45
+ MODEL_ID = os.getenv("MODEL_ID", "unsloth/Qwen3-30B-A3B")
46
+ USE_INT8 = os.getenv("USE_INT8", "0") == "1" # set env var to 1 for 8‑bit
47
+ THINKING = os.getenv("DEFAULT_THINKING", "1") == "1" # default reasoning mode
48
+
49
+ DTYPE = torch.bfloat16 # Hopper bf16 fast‑path
50
+ bnb_cfg = BitsAndBytesConfig(load_in_8bit=True) if USE_INT8 else None
51
+
52
+ print(f"πŸ”„ Loading {MODEL_ID} ({'8‑bit' if USE_INT8 else 'bf16'}) …")
53
+
54
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, trust_remote_code=True)
55
+ model = AutoModelForCausalLM.from_pretrained(
56
+ MODEL_ID,
57
+ device_map="auto",
58
+ torch_dtype=(None if USE_INT8 else DTYPE),
59
+ quantization_config=bnb_cfg,
60
+ trust_remote_code=True,
61
+ ).eval()
62
+ DEVICE = model.device
63
+ print("βœ… Model ready.")
64
+
65
  for d in ASSETS_DIRS:
66
  os.makedirs(d, exist_ok=True)
67
 
 
103
  f"Instruction: {instruction.strip()}\n"
104
  f"πŸ”΄ Strict target duration: {target_duration}s β€” β‰ˆ {approx_words} words (must be respected)."
105
  )
106
+ script = generate_script(model,tokenizer,prompt)
107
 
108
+ title = generate_title(model,tokenizer,script)
109
+ description = generate_description(model,tokenizer,script)
110
  return script, title, description, script # last return for state update
111
 
112
 
scripts/generate_scripts.py CHANGED
@@ -12,14 +12,9 @@ from transformers import AutoModelForCausalLM, AutoTokenizer
12
 
13
 
14
  @spaces.GPU()
15
- def generate_local(prompt: str, max_new_tokens: int = 350, temperature: float = 0.7) -> str:
16
- model_id = "Qwen/Qwen3-0.6B"
17
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # get the device the model is on
18
-
19
- tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True)
20
- model = AutoModelForCausalLM.from_pretrained(model_id, torch_dtype=torch.float32, trust_remote_code=True).to(device)
21
  inputs = tokenizer(prompt, return_tensors="pt").to(device)
22
-
23
  output_ids = model.generate(
24
  **inputs,
25
  max_new_tokens=max_new_tokens,
@@ -31,7 +26,7 @@ def generate_local(prompt: str, max_new_tokens: int = 350, temperature: float =
31
 
32
 
33
 
34
- def generate_script(prompt: str, word_count: int = 60) -> str:
35
  system_prompt = (
36
  "You are an expert YouTube scriptwriter. "
37
  "Your job is to write the EXACT words that will be spoken aloud in a video. "
@@ -44,15 +39,15 @@ def generate_script(prompt: str, word_count: int = 60) -> str:
44
  "- Do NOT include any explanations, labels, or headers. Only output the final spoken script.\n\n"
45
  "Start now:"
46
  )
47
- return generate_local(system_prompt)
48
 
49
 
50
- def one_word(query: str) -> str:
51
  prompt_final = (
52
  "Extract only the unique central theme of the following text in English in JSON format like this: "
53
  '{"keyword": "impact"}. Text: ' + query
54
  )
55
- result = generate_local(prompt_final, max_new_tokens=30, temperature=0.4)
56
  try:
57
  keyword_json = json.loads(result)
58
  keyword = keyword_json.get("keyword", "")
@@ -62,14 +57,14 @@ def one_word(query: str) -> str:
62
  return keyword.lower()
63
 
64
 
65
- def generate_title(text: str) -> str:
66
  prompt_final = (
67
  "Generate a unique title for a YouTube Short video that is engaging and informative, "
68
  "maximum 100 characters, without emojis, introduction, or explanation. Content:\n" + text
69
  )
70
- return generate_local(prompt_final, max_new_tokens=50, temperature=0.9).strip()
71
 
72
- def generate_description(text: str) -> str:
73
  prompt_final = (
74
  "Write only the YouTube video description in English:\n"
75
  "1. A compelling opening line.\n"
@@ -77,13 +72,13 @@ def generate_description(text: str) -> str:
77
  "3. End with 3 relevant hashtags.\n"
78
  "No emojis or introductions. Here is the text:\n" + text
79
  )
80
- return generate_local(prompt_final, max_new_tokens=300, temperature=0.7).strip()
81
 
82
- def generate_tags(text: str) -> list:
83
  prompt_final = (
84
  "List only the important keywords for this YouTube video, separated by commas, "
85
  "maximum 10 keywords. Context: " + text
86
  )
87
- result = generate_local(prompt_final, max_new_tokens=100, temperature=0.5)
88
  return [tag.strip() for tag in result.split(",") if tag.strip()]
89
 
 
12
 
13
 
14
  @spaces.GPU()
15
+ def generate_local(model,tokenizer, prompt: str, max_new_tokens: int = 350, temperature: float = 0.7) -> str:
 
16
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # get the device the model is on
 
 
 
17
  inputs = tokenizer(prompt, return_tensors="pt").to(device)
 
18
  output_ids = model.generate(
19
  **inputs,
20
  max_new_tokens=max_new_tokens,
 
26
 
27
 
28
 
29
+ def generate_script(model,tokenizer, prompt: str, word_count: int = 60) -> str:
30
  system_prompt = (
31
  "You are an expert YouTube scriptwriter. "
32
  "Your job is to write the EXACT words that will be spoken aloud in a video. "
 
39
  "- Do NOT include any explanations, labels, or headers. Only output the final spoken script.\n\n"
40
  "Start now:"
41
  )
42
+ return generate_local(model,tokenizer, system_prompt)
43
 
44
 
45
+ def one_word(model,tokenizer, query: str) -> str:
46
  prompt_final = (
47
  "Extract only the unique central theme of the following text in English in JSON format like this: "
48
  '{"keyword": "impact"}. Text: ' + query
49
  )
50
+ result = generate_local(model,tokenizer, prompt_final, max_new_tokens=30, temperature=0.4)
51
  try:
52
  keyword_json = json.loads(result)
53
  keyword = keyword_json.get("keyword", "")
 
57
  return keyword.lower()
58
 
59
 
60
+ def generate_title(model,tokenizer, text: str) -> str:
61
  prompt_final = (
62
  "Generate a unique title for a YouTube Short video that is engaging and informative, "
63
  "maximum 100 characters, without emojis, introduction, or explanation. Content:\n" + text
64
  )
65
+ return generate_local(model,tokenizer, prompt_final, max_new_tokens=50, temperature=0.9).strip()
66
 
67
+ def generate_description(model,tokenizer, text: str) -> str:
68
  prompt_final = (
69
  "Write only the YouTube video description in English:\n"
70
  "1. A compelling opening line.\n"
 
72
  "3. End with 3 relevant hashtags.\n"
73
  "No emojis or introductions. Here is the text:\n" + text
74
  )
75
+ return generate_local(model,tokenizer, prompt_final, max_new_tokens=300, temperature=0.7).strip()
76
 
77
+ def generate_tags(model,tokenizer, text: str) -> list:
78
  prompt_final = (
79
  "List only the important keywords for this YouTube video, separated by commas, "
80
  "maximum 10 keywords. Context: " + text
81
  )
82
+ result = generate_local(model,tokenizer, prompt_final, max_new_tokens=100, temperature=0.5)
83
  return [tag.strip() for tag in result.split(",") if tag.strip()]
84