1inkusFace commited on
Commit
7a6bf95
·
verified ·
1 Parent(s): df7b4d1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +89 -104
app.py CHANGED
@@ -1,108 +1,92 @@
1
  import spaces # If using Hugging Face Spaces
 
2
  import os
3
- # ## GGUF MOD: Unused environment variables for PyTorch have been removed.
4
- # ## GGUF MOD: ctransformers handles its own memory and GPU management.
5
  os.putenv('PYTORCH_NVML_BASED_CUDA_CHECK','1')
6
- # os.putenv('TORCH_LINALG_PREFER_CUSOLVER','1')
7
- # alloc_conf_parts = [
8
- # 'expandable_segments:True',
9
- # 'pinned_use_background_threads:True'
10
- # ]
11
- # os.environ['PYTORCH_CUDA_ALLOC_CONF'] = ','.join(alloc_conf_parts)
12
- # os.environ["SAFETENSORS_FAST_GPU"] = "1"
13
  os.putenv('HF_HUB_ENABLE_HF_TRANSFER','1')
 
 
14
  import torch
15
  import gradio as gr
16
 
17
-
18
-
19
- # ## GGUF MOD: Import AutoModelForCausalLM from ctransformers instead of transformers.
20
- # ## GGUF MOD: BitsAndBytesConfig is no longer needed.
21
- from ctransformers import AutoModelForCausalLM
22
- from transformers import AutoTokenizer
23
- from image_gen_aux import UpscaleWithModel
24
-
25
- # ## GGUF MOD: PyTorch backend settings are not used by ctransformers.
26
  torch.backends.cuda.matmul.allow_tf32 = True
27
- # ... (rest of torch settings removed for clarity)
 
 
 
 
 
28
 
29
  # --- Model and Tokenizer Configuration ---
30
- # ## GGUF MOD: The model name now points to the GGUF repository.
31
- model_repo_id = "Quant-Cartel/MilkDropLM-32b-v0.3-GGUF"
32
- # ## GGUF MOD: Specify the exact GGUF file to download.
33
- # It's good practice to pick a specific quantization level.
34
- # q4_K_M is a good balance of quality and performance.
35
- model_file = "MilkDropLM-32b-v0.3-Q4_K_M.gguf"
36
-
37
- # ## GGUF MOD: The quantization is handled by ctransformers when loading the model.
38
- # ## The BitsAndBytesConfig is removed.
39
- print("Loading GGUF model...")
40
- # Documentation: Loading GGUF Model with ctransformers
41
- # We use AutoModelForCausalLM from the ctransformers library.
42
- # - model_repo_id: The Hugging Face repository containing the GGUF files.
43
- # - model_file: The specific .gguf file to download and load.
44
- # - model_type: 'llama' is specified as it's a Llama-based model, which helps ctransformers optimize.
45
- # - gpu_layers: This is the most important parameter for performance. It determines
46
- # how many layers of the model are offloaded to the GPU. 50 is a high value
47
- # that should fill most of the VRAM on modern GPUs for a 32B model,
48
- # leading to much faster inference. Adjust this number based on your VRAM.
49
- # - hf=True: This tells ctransformers to download from the Hugging Face Hub.
50
-
51
- upscaler = UpscaleWithModel.from_pretrained("Kim2091/ClearRealityV1").to(torch.device('cuda'))
52
- upscaler.to(torch.device('cpu'))
53
-
54
- def loadModel():
55
- device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
56
- model = AutoModelForCausalLM.from_pretrained(
57
- model_repo_id,
58
- model_file=model_file,
59
- model_type='llama',
60
- threads=16,
61
- gpu_layers=50, # Offload all possible layers to GPU
62
- hf=True
63
- )
64
- return model
65
-
66
- device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
67
-
68
- model = loadModel()
69
- print("GGUF Model loaded successfully.")
70
-
71
- # The tokenizer can still be loaded from the original repository.
72
- # GGUF files do not contain tokenizer data.
73
- tokenizer_repo_id = "InferenceIllusionist/MilkDropLM-32b-v0.3"
74
- print(f"Loading tokenizer from: {tokenizer_repo_id}")
75
  tokenizer = AutoTokenizer.from_pretrained(
76
- tokenizer_repo_id,
77
  use_fast=True
78
  )
79
 
80
- # ** This part remains the same. The chat template is independent of the model format. **
 
 
 
 
 
81
  VICUNA_CHAT_TEMPLATE = (
82
- "{% if messages[0]['role'] == 'system' %}"
83
- "{{ messages[0]['content'] + '\\n\\n' }}"
84
- "{% set loop_messages = messages[1:] %}"
85
  "{% else %}"
86
- "{% set loop_messages = messages %}"
87
  "{% endif %}"
88
- "{% for message in loop_messages %}"
89
  "{% if message['role'] == 'user' %}"
90
  "{{ 'USER: ' + message['content'].strip() + '\\n' }}"
91
  "{% elif message['role'] == 'assistant' %}"
92
  "{{ 'ASSISTANT: ' + message['content'].strip() + eos_token + '\\n' }}"
93
  "{% endif %}"
94
  "{% endfor %}"
95
- "{% if add_generation_prompt %}"
96
- "{% if messages[-1]['role'] != 'assistant' %}"
97
- "{{ 'ASSISTANT:' }}"
98
  "{% endif %}"
99
  "{% endif %}"
100
  )
101
  tokenizer.chat_template = VICUNA_CHAT_TEMPLATE
102
  print("Manually set Vicuna chat template on the tokenizer.")
103
 
 
104
  if tokenizer.pad_token is None:
105
  tokenizer.pad_token = tokenizer.eos_token
 
 
 
 
106
  print(f"Tokenizer `pad_token` was None, set to `eos_token`: {tokenizer.eos_token}")
107
 
108
 
@@ -113,45 +97,46 @@ def generate_code(prompt: str) -> str:
113
  {"role": "user", "content": prompt}
114
  ]
115
  try:
116
- # The chat template application is the same.
 
117
  text = tokenizer.apply_chat_template(
118
  messages,
119
  tokenize=False,
120
- add_generation_prompt=True
121
  )
122
- print(f"Formatted prompt using chat template:\n{text}")
123
  except Exception as e:
124
  print(f"Error applying chat template: {e}")
125
- return f"Error: Could not apply chat template. Details: {e}."
126
-
127
- # ## GGUF MOD: The generation call is now simpler.
128
- # The `ctransformers` model object takes the prompt text directly.
129
- # No need for tokenization or sending tensors to a device manually.
130
-
131
- # Documentation: Generating Text with ctransformers
132
- # The model object has a built-in generator that you call like a function.
133
- # - prompt (text): The formatted string prompt for the model.
134
- # - max_new_tokens, temperature, top_p: These parameters function identically
135
- # to their Hugging Face counterparts.
136
- # - stop: We can provide the EOS token to ensure the model stops generating
137
- # cleanly once it thinks it's finished.
138
- # The output is a simple string.
139
- response = model(
140
- text,
141
- max_new_tokens=2048,
142
- temperature=0.7,
143
- top_p=0.9,
144
- stop=[tokenizer.eos_token],
145
- )
146
 
 
 
147
  return response.strip()
148
 
149
- # --- Gradio Interface (No changes needed here) ---
150
- with gr.Blocks(title="Vicuna 32B Milkdrop GGUF") as demo:
151
  with gr.Tab("Code Chat"):
152
- gr.Markdown("# Vicuna 32B Milkdrop (GGUF)\nProvide a prompt to generate HLSL.")
153
  with gr.Row():
154
- prompt_input = gr.Textbox(
155
  label="Prompt",
156
  show_label=True,
157
  lines=3,
@@ -159,10 +144,10 @@ with gr.Blocks(title="Vicuna 32B Milkdrop GGUF") as demo:
159
  )
160
  run_button = gr.Button("Generate Code", variant="primary")
161
  with gr.Row():
162
- result_output = gr.Code(
163
  label="Generated Code",
164
  show_label=True,
165
- language="hlsl", # Changed to hlsl for better syntax highlighting
166
  lines=20,
167
  )
168
  gr.on(
 
1
  import spaces # If using Hugging Face Spaces
2
+
3
  import os
4
+
 
5
  os.putenv('PYTORCH_NVML_BASED_CUDA_CHECK','1')
6
+ os.putenv('TORCH_LINALG_PREFER_CUSOLVER','1')
7
+ alloc_conf_parts = [
8
+ 'expandable_segments:True',
9
+ 'pinned_use_background_threads:True' # Specific to pinned memory.
10
+ ]
11
+ os.environ['PYTORCH_CUDA_ALLOC_CONF'] = ','.join(alloc_conf_parts)
12
+ os.environ["SAFETENSORS_FAST_GPU"] = "1"
13
  os.putenv('HF_HUB_ENABLE_HF_TRANSFER','1')
14
+
15
+ from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig # Import BitsAndBytesConfig
16
  import torch
17
  import gradio as gr
18
 
 
 
 
 
 
 
 
 
 
19
  torch.backends.cuda.matmul.allow_tf32 = True
20
+ torch.backends.cuda.matmul.allow_bf16_reduced_precision_reduction = True
21
+ torch.backends.cuda.matmul.allow_fp16_reduced_precision_reduction = True
22
+ torch.backends.cudnn.allow_tf32 = True
23
+ torch.backends.cudnn.deterministic = True
24
+ torch.backends.cudnn.benchmark = True
25
+ torch.set_float32_matmul_precision("high")
26
 
27
  # --- Model and Tokenizer Configuration ---
28
+ model_name = "InferenceIllusionist/MilkDropLM-7b-v0.3"
29
+
30
+ # --- Quantization Configuration (Example: 4-bit) ---
31
+ # This section is included based on our previous discussion.
32
+ # Remove or comment out if you are not using quantization.
33
+ print("Setting up 4-bit quantization config...")
34
+ quantization_config_4bit = BitsAndBytesConfig(
35
+ load_in_4bit=True,
36
+ bnb_4bit_use_double_quant=True,
37
+ bnb_4bit_quant_type="nf4",
38
+ bnb_4bit_compute_dtype=torch.float16
39
+ )
40
+
41
+ print(f"Loading model: {model_name} with quantization")
42
+ model = AutoModelForCausalLM.from_pretrained(
43
+ model_name,
44
+ quantization_config=quantization_config_4bit, # Comment out if not using quantization
45
+ device_map="auto",
46
+ )
47
+
48
+ print(f"Loading tokenizer: {model_name}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  tokenizer = AutoTokenizer.from_pretrained(
50
+ model_name,
51
  use_fast=True
52
  )
53
 
54
+ # ** MODIFICATION: Define and set the Vicuna chat template **
55
+ # ** DOCUMENTATION: Chat Template **
56
+ # Vicuna models expect a specific chat format. If the tokenizer doesn't have one
57
+ # built-in, we need to set it manually.
58
+ # This template handles a system prompt, user messages, and assistant responses.
59
+ # It will also add the "ASSISTANT:" prompt for generation if needed.
60
  VICUNA_CHAT_TEMPLATE = (
61
+ "{% if messages[0]['role'] == 'system' %}" # Check if the first message is a system prompt
62
+ "{{ messages[0]['content'] + '\\n\\n' }}" # Add system prompt with two newlines
63
+ "{% set loop_messages = messages[1:] %}" # Slice to loop over remaining messages
64
  "{% else %}"
65
+ "{% set loop_messages = messages %}" # No system prompt, loop over all messages
66
  "{% endif %}"
67
+ "{% for message in loop_messages %}" # Loop through user and assistant messages
68
  "{% if message['role'] == 'user' %}"
69
  "{{ 'USER: ' + message['content'].strip() + '\\n' }}"
70
  "{% elif message['role'] == 'assistant' %}"
71
  "{{ 'ASSISTANT: ' + message['content'].strip() + eos_token + '\\n' }}"
72
  "{% endif %}"
73
  "{% endfor %}"
74
+ "{% if add_generation_prompt %}" # If we need to prompt the model for a response
75
+ "{% if messages[-1]['role'] != 'assistant' %}" # And the last message wasn't from the assistant
76
+ "{{ 'ASSISTANT:' }}" # Add the assistant prompt
77
  "{% endif %}"
78
  "{% endif %}"
79
  )
80
  tokenizer.chat_template = VICUNA_CHAT_TEMPLATE
81
  print("Manually set Vicuna chat template on the tokenizer.")
82
 
83
+
84
  if tokenizer.pad_token is None:
85
  tokenizer.pad_token = tokenizer.eos_token
86
+ # Also update the model config's pad_token_id if you are setting tokenizer.pad_token
87
+ # This is crucial if the model's config doesn't get updated automatically.
88
+ if model.config.pad_token_id is None:
89
+ model.config.pad_token_id = tokenizer.pad_token_id
90
  print(f"Tokenizer `pad_token` was None, set to `eos_token`: {tokenizer.eos_token}")
91
 
92
 
 
97
  {"role": "user", "content": prompt}
98
  ]
99
  try:
100
+ # ** DOCUMENTATION: Applying Chat Template **
101
+ # Now that tokenizer.chat_template is set, this should work.
102
  text = tokenizer.apply_chat_template(
103
  messages,
104
  tokenize=False,
105
+ add_generation_prompt=True # Important to append "ASSISTANT:"
106
  )
107
+ print(f"Formatted prompt using chat template:\n{text}") # For debugging
108
  except Exception as e:
109
  print(f"Error applying chat template: {e}")
110
+ # Provide a more informative error or fallback if needed
111
+ return f"Error: Could not apply chat template. Details: {e}. Ensure the tokenizer has a valid `chat_template` attribute."
112
+
113
+ # Determine device for inputs if model is on multiple devices
114
+ # For device_map="auto", input tensors should go to the device of the first model block.
115
+ input_device = model.hf_device_map.get("", next(iter(model.hf_device_map.values()))) if hasattr(model, "hf_device_map") else model.device
116
+
117
+ model_inputs = tokenizer([text], return_tensors="pt").to(input_device)
118
+
119
+ with torch.no_grad():
120
+ generated_ids = model.generate(
121
+ **model_inputs, # Pass tokenized inputs
122
+ max_new_tokens=2048,
123
+ min_new_tokens=768,
124
+ do_sample=True,
125
+ temperature=0.7,
126
+ top_p=0.9,
127
+ pad_token_id=tokenizer.eos_token_id # Use EOS token for padding
128
+ )
 
 
129
 
130
+ response_ids = generated_ids[0][len(model_inputs.input_ids[0]):]
131
+ response = tokenizer.decode(response_ids, skip_special_tokens=True)
132
  return response.strip()
133
 
134
+ # --- Gradio Interface ---
135
+ with gr.Blocks(title="Vicuna 32B Milkdrop") as demo:
136
  with gr.Tab("Code Chat"):
137
+ gr.Markdown("# Vicuna 32B Milkdrop\nProvide a prompt to generate HLSL.")
138
  with gr.Row():
139
+ prompt_input = gr.Textbox( # Renamed to avoid conflict with 'prompt' variable in function scope
140
  label="Prompt",
141
  show_label=True,
142
  lines=3,
 
144
  )
145
  run_button = gr.Button("Generate Code", variant="primary")
146
  with gr.Row():
147
+ result_output = gr.Code( # Renamed
148
  label="Generated Code",
149
  show_label=True,
150
+ language="python",
151
  lines=20,
152
  )
153
  gr.on(