ChintanSatva commited on
Commit
175aecd
·
verified ·
1 Parent(s): 8ad9e4a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +20 -19
app.py CHANGED
@@ -3,11 +3,12 @@ import logging
3
  import json
4
  import os
5
  from pydantic import BaseModel
6
- from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
7
  import torch
8
  import psutil
9
  import cachetools
10
  import hashlib
 
11
 
12
  # Set environment variable for cache
13
  os.environ["HF_HOME"] = "/app/cache"
@@ -24,13 +25,13 @@ try:
24
  tokenizer = AutoTokenizer.from_pretrained("hf-internal-testing/llama-tokenizer", cache_dir="/app/cache")
25
  model = AutoModelForCausalLM.from_pretrained(
26
  model_name,
27
- torch_dtype=torch.float32,
28
  device_map="cpu",
29
  low_cpu_mem_usage=True,
30
  cache_dir="/app/cache",
31
- trust_remote_code=True
 
32
  )
33
- pipe = pipeline("text-generation", model=model, tokenizer=tokenizer, max_new_tokens=512)
34
  except Exception as e:
35
  logger.error(f"Failed to load BitNet model: {str(e)}")
36
  raise HTTPException(status_code=500, detail=f"BitNet model initialization failed: {str(e)}")
@@ -48,7 +49,7 @@ def get_text_hash(text: str):
48
  """Generate MD5 hash of text."""
49
  return hashlib.md5(text.encode('utf-8')).hexdigest()
50
 
51
- # Allowed categories and subcategories
52
  ALLOWED_CATEGORIES = [
53
  {"name": "income", "subcategories": ["dividends", "interest earned", "retirement pension", "tax refund", "unemployment", "wages", "other income"]},
54
  {"name": "transfer in", "subcategories": ["cash advances and loans", "deposit", "investment and retirement funds", "savings", "account transfer", "other transfer in"]},
@@ -87,29 +88,29 @@ async def categorize_with_bitnet(description: str, amount: float):
87
  return structured_data_cache[text_hash]
88
 
89
  try:
90
- prompt = f"""You are an expert financial transaction categorizer using BitNet b1.2-3B. Given a transaction description and amount, categorize it into the specified categories and subcategories. Assign confidence scores (0 to 1). Follow these rules:
91
- - Select category and subcategory from this list (case-insensitive, use exact names):
92
- {', '.join([f'{c["name"]} ({", ".join(c["subcategories"])})' for c in ALLOWED_CATEGORIES])}
93
- - For positive amounts, use 'income' and one of its subcategories.
94
- - If unsure, set confidence to 0.7.
95
- - If no match, use 'miscellaneous' and 'other'.
96
- - Do NOT add markdown or explanations, only output valid JSON.
97
 
98
  Description: {description}
99
  Amount: {amount}
100
 
101
- Output JSON:
102
  {{
103
  "category": "",
104
  "subcategory": "",
105
  "category_confidence": 0.0,
106
  "subcategory_confidence": 0.0
107
- }}
108
- """
109
- outputs = pipe(prompt)[0]["generated_text"]
110
- json_start = outputs.rfind("{")
111
- json_end = outputs.rfind("}") + 1
112
- result = json.loads(outputs[json_start:json_end])
 
 
 
 
 
 
113
 
114
  # Normalize category and subcategory
115
  def normalize(s):
 
3
  import json
4
  import os
5
  from pydantic import BaseModel
6
+ from transformers import AutoModelForCausalLM, AutoTokenizer
7
  import torch
8
  import psutil
9
  import cachetools
10
  import hashlib
11
+ from bitsandbytes import quantize
12
 
13
  # Set environment variable for cache
14
  os.environ["HF_HOME"] = "/app/cache"
 
25
  tokenizer = AutoTokenizer.from_pretrained("hf-internal-testing/llama-tokenizer", cache_dir="/app/cache")
26
  model = AutoModelForCausalLM.from_pretrained(
27
  model_name,
28
+ torch_dtype=torch.float16,
29
  device_map="cpu",
30
  low_cpu_mem_usage=True,
31
  cache_dir="/app/cache",
32
+ trust_remote_code=True,
33
+ quantization_config={"load_in_4bit": True} # 4-bit quantization
34
  )
 
35
  except Exception as e:
36
  logger.error(f"Failed to load BitNet model: {str(e)}")
37
  raise HTTPException(status_code=500, detail=f"BitNet model initialization failed: {str(e)}")
 
49
  """Generate MD5 hash of text."""
50
  return hashlib.md5(text.encode('utf-8')).hexdigest()
51
 
52
+ # Simplified categories (reference only, not included in prompt)
53
  ALLOWED_CATEGORIES = [
54
  {"name": "income", "subcategories": ["dividends", "interest earned", "retirement pension", "tax refund", "unemployment", "wages", "other income"]},
55
  {"name": "transfer in", "subcategories": ["cash advances and loans", "deposit", "investment and retirement funds", "savings", "account transfer", "other transfer in"]},
 
88
  return structured_data_cache[text_hash]
89
 
90
  try:
91
+ # Simplified prompt
92
+ prompt = f"""Categorize this transaction into a category and subcategory with confidence scores (0 to 1). Use 'income' for positive amounts. If unsure, use confidence 0.7 and 'miscellaneous'/'other' if no match. Output only JSON.
 
 
 
 
 
93
 
94
  Description: {description}
95
  Amount: {amount}
96
 
 
97
  {{
98
  "category": "",
99
  "subcategory": "",
100
  "category_confidence": 0.0,
101
  "subcategory_confidence": 0.0
102
+ }}"""
103
+ inputs = tokenizer(prompt, return_tensors="pt").to("cpu")
104
+ outputs = model.generate(
105
+ **inputs,
106
+ max_new_tokens=100, # Reduced for speed
107
+ do_sample=False,
108
+ num_beams=1
109
+ )
110
+ json_str = tokenizer.decode(outputs[0], skip_special_tokens=True)
111
+ json_start = json_str.rfind("{")
112
+ json_end = json_str.rfind("}") + 1
113
+ result = json.loads(json_str[json_start:json_end])
114
 
115
  # Normalize category and subcategory
116
  def normalize(s):