samurai9776 commited on
Commit
4233284
·
verified ·
1 Parent(s): 6f8e194

Upload folder using huggingface_hub

Browse files
Files changed (2) hide show
  1. config.json +9 -0
  2. pipeline.py +110 -0
config.json CHANGED
@@ -28,5 +28,14 @@
28
  "label2id": {
29
  "INCOMPLETE": 0,
30
  "COMPLETE": 1
 
 
 
 
 
 
 
 
 
31
  }
32
  }
 
28
  "label2id": {
29
  "INCOMPLETE": 0,
30
  "COMPLETE": 1
31
+ },
32
+ "custom_pipelines": {
33
+ "text-classification": {
34
+ "impl": "pipeline.ThoughtCompletionPipeline",
35
+ "pt": [
36
+ "DistilBertForSequenceClassification"
37
+ ],
38
+ "tf": []
39
+ }
40
  }
41
  }
pipeline.py ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import re
3
+ import torch
4
+ from transformers import Pipeline
5
+
6
+ class ThoughtCompletionPipeline(Pipeline):
7
+ """Custom pipeline with linguistic rules for thought completion classification"""
8
+
9
+ INCOMPLETE_ENDING_WORDS = [
10
+ 'a', 'and', 'with', 'do', 'but', 'to', 'for', 'of', 'or', 'what', 'get',
11
+ 'the', 'have', 'need', 'want', 'can', 'will', 'would', 'could', 'should',
12
+ 'also', 'add', 'plus', 'oh', 'um', 'uh'
13
+ ]
14
+
15
+ def _sanitize_parameters(self, **kwargs):
16
+ return {}, {}, {}
17
+
18
+ def ends_with_incomplete_word(self, text):
19
+ """Check if text ends with words that indicate incomplete thought"""
20
+ text = text.strip().lower()
21
+ text = re.sub(r'[.,!?;]$', '', text)
22
+ words = text.split()
23
+
24
+ if not words:
25
+ return False
26
+
27
+ last_word = words[-1]
28
+ return last_word in self.INCOMPLETE_ENDING_WORDS
29
+
30
+ def apply_linguistic_rules(self, text):
31
+ """Apply linguistic rules to determine if thought is incomplete"""
32
+ # Expecting format: "AI_utterance [SEP] CX_utterance"
33
+ parts = text.split('[SEP]')
34
+ if len(parts) != 2:
35
+ return None, None
36
+
37
+ ai_utterance = parts[0].strip()
38
+ cx_utterance = parts[1].strip()
39
+
40
+ # Check if customer utterance ends with incomplete word
41
+ if self.ends_with_incomplete_word(cx_utterance):
42
+ return [{'label': 'INCOMPLETE', 'score': 0.95}], 'rule:incomplete_ending'
43
+
44
+ cx_lower = cx_utterance.lower()
45
+
46
+ # Complete thought indicators
47
+ complete_phrases = [
48
+ "that's all", "nothing else", "i'm done", "that's it",
49
+ "no thanks", "no thank you", "yes", "yes please",
50
+ "perfect", "great", "sounds good", "that's everything"
51
+ ]
52
+
53
+ for phrase in complete_phrases:
54
+ if phrase in cx_lower:
55
+ return [{'label': 'COMPLETE', 'score': 0.95}], f'rule:contains_{phrase}'
56
+
57
+ # Incomplete thought indicators
58
+ incomplete_phrases = [
59
+ "let me add", "actually", "wait", "i also need",
60
+ "can i get", "i want", "i'd like", "i need",
61
+ "hold on", "one more", "oh and"
62
+ ]
63
+
64
+ for phrase in incomplete_phrases:
65
+ if phrase in cx_lower:
66
+ return [{'label': 'INCOMPLETE', 'score': 0.95}], f'rule:contains_{phrase}'
67
+
68
+ return None, None
69
+
70
+ def preprocess(self, inputs):
71
+ # First check rules
72
+ rule_result, rule_applied = self.apply_linguistic_rules(inputs)
73
+ if rule_result:
74
+ return {"rule_result": rule_result, "use_model": False}
75
+
76
+ # If no rule applies, prepare for model
77
+ return {"inputs": inputs, "use_model": True}
78
+
79
+ def _forward(self, model_inputs):
80
+ if not model_inputs["use_model"]:
81
+ return {"predictions": model_inputs["rule_result"]}
82
+
83
+ # Use the model
84
+ inputs = self.tokenizer(
85
+ model_inputs["inputs"],
86
+ return_tensors="pt",
87
+ truncation=True,
88
+ padding=True,
89
+ max_length=128
90
+ )
91
+
92
+ with torch.no_grad():
93
+ outputs = self.model(**inputs)
94
+ predictions = torch.nn.functional.softmax(outputs.logits, dim=-1)
95
+
96
+ return {"predictions": predictions}
97
+
98
+ def postprocess(self, model_outputs):
99
+ if isinstance(model_outputs["predictions"], list):
100
+ # Rule-based result
101
+ return model_outputs["predictions"]
102
+
103
+ # Model-based result
104
+ predictions = model_outputs["predictions"]
105
+ scores = predictions.numpy()[0]
106
+
107
+ return [
108
+ {"label": "INCOMPLETE", "score": float(scores[0])},
109
+ {"label": "COMPLETE", "score": float(scores[1])}
110
+ ]