Halfotter commited on
Commit
25b8ff1
·
verified ·
1 Parent(s): f2aff49

Upload inference.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. inference.py +60 -47
inference.py CHANGED
@@ -4,54 +4,66 @@ import torch.nn.functional as F
4
  import numpy as np
5
  import json
6
  import os
7
- from transformers import PreTrainedModel, PretrainedConfig
8
 
9
- class SteelConfig(PretrainedConfig):
10
- """철강 분류기 설정"""
11
- model_type = "steel_classifier"
12
 
13
- def __init__(self, input_size=3000, hidden_size=256, intermediate_size=128, num_labels=66, **kwargs):
14
  super().__init__(**kwargs)
15
- self.input_size = input_size
16
- self.hidden_size = hidden_size
17
- self.intermediate_size = intermediate_size
18
  self.num_labels = num_labels
19
 
20
- class SteelModel(PreTrainedModel):
21
- """Hugging Face 표준 철강 분류기"""
22
- config_class = SteelConfig
23
 
24
  def __init__(self, config):
25
  super().__init__(config)
26
 
27
- # 신경망 레이어
28
- self.fc1 = nn.Linear(config.input_size, config.hidden_size)
29
- self.fc2 = nn.Linear(config.hidden_size, config.intermediate_size)
30
- self.fc3 = nn.Linear(config.intermediate_size, config.num_labels)
 
 
 
 
 
 
 
31
  self.dropout = nn.Dropout(0.3)
32
 
33
- # 라벨 매핑
34
- self.id2label = config.id2label if hasattr(config, 'id2label') else {}
35
- self.label2id = config.label2id if hasattr(config, 'label2id') else {}
 
 
 
36
 
37
  def forward(self, input_ids=None, attention_mask=None, labels=None, **kwargs):
38
- """표준 Hugging Face forward"""
39
- # TF-IDF 벡터화 (input_ids를 텍스트로 변환)
40
  if input_ids is not None:
41
- # input_ids를 텍스트로 변환하는 로직
42
- batch_size = input_ids.shape[0]
43
- features = torch.zeros(batch_size, self.config.input_size)
44
-
45
- for i in range(batch_size):
46
- # 간단한 벡터화 (실제로는 더 정교한 TF-IDF 필요)
47
- text_vector = self._simple_vectorize(input_ids[i])
48
- features[i] = torch.FloatTensor(text_vector)
49
  else:
50
- # 기본값
51
- features = torch.zeros(1, self.config.input_size)
52
 
53
- # 신경망 통과
54
- x = F.relu(self.fc1(features))
 
 
 
 
 
 
 
 
55
  x = self.dropout(x)
56
  x = F.relu(self.fc2(x))
57
  x = self.dropout(x)
@@ -65,12 +77,13 @@ class SteelModel(PreTrainedModel):
65
 
66
  return {"loss": loss, "logits": logits} if loss is not None else {"logits": logits}
67
 
68
- def _simple_vectorize(self, input_ids):
69
- """간단한 벡터"""
70
- vector = np.zeros(self.config.input_size)
 
71
  # input_ids를 기반으로 벡터 생성
72
  for token_id in input_ids:
73
- if token_id < self.config.input_size:
74
  vector[token_id] += 1
75
 
76
  if np.sum(vector) > 0:
@@ -90,19 +103,18 @@ def load_model():
90
  with open(config_path, 'r', encoding='utf-8') as f:
91
  config_data = json.load(f)
92
 
93
- # SteelConfig 생성
94
- config = SteelConfig(
95
- input_size=config_data['input_size'],
96
- hidden_size=config_data['hidden_size'],
97
- intermediate_size=config_data['intermediate_size'],
98
  num_labels=config_data['num_labels'],
99
  id2label=config_data['id2label'],
100
- label2id=config_data['label2id']
 
 
101
  )
102
 
103
  # 모델 생성 및 로드
104
- model = SteelModel(config)
105
- model_path = os.path.join(os.getcwd(), "integrated_model.bin")
106
  model.load_state_dict(torch.load(model_path, map_location='cpu'))
107
  model.eval()
108
 
@@ -124,13 +136,14 @@ def predict(inputs):
124
  else:
125
  text = str(inputs)
126
 
127
- # 텍스트를 간단한 토큰 ID로 변환
128
  tokens = text.lower().split()
129
- input_ids = torch.tensor([[hash(token) % model.config.input_size for token in tokens]])
 
130
 
131
  # 예측
132
  with torch.no_grad():
133
- outputs = model(input_ids=input_ids)
134
  logits = outputs["logits"]
135
  probabilities = F.softmax(logits, dim=1)
136
  predicted_class = torch.argmax(probabilities, dim=1).item()
 
4
  import numpy as np
5
  import json
6
  import os
7
+ from transformers import PreTrainedModel, PretrainedConfig, XLMRobertaModel, XLMRobertaConfig
8
 
9
+ class XLMSteelConfig(PretrainedConfig):
10
+ """XLM-RoBERTa 철강 분류기 설정"""
11
+ model_type = "xlm_steel_classifier"
12
 
13
+ def __init__(self, num_labels=66, **kwargs):
14
  super().__init__(**kwargs)
 
 
 
15
  self.num_labels = num_labels
16
 
17
+ class XLMIntegratedModel(PreTrainedModel):
18
+ """XLM-RoBERTa + TF-IDF 통합 모델"""
19
+ config_class = XLMSteelConfig
20
 
21
  def __init__(self, config):
22
  super().__init__(config)
23
 
24
+ # XLM-RoBERTa 모델
25
+ self.xlm_roberta = XLMRobertaModel.from_pretrained('xlm-roberta-base')
26
+
27
+ # TF-IDF 벡터라이저 정보 저장
28
+ self.feature_names = getattr(config, 'feature_names', [])
29
+ self.input_size = getattr(config, 'input_size', 3000)
30
+
31
+ # 신경망 레이어 (기존 TF-IDF 모델 구조)
32
+ self.fc1 = nn.Linear(self.input_size, 256)
33
+ self.fc2 = nn.Linear(256, 128)
34
+ self.fc3 = nn.Linear(128, config.num_labels)
35
  self.dropout = nn.Dropout(0.3)
36
 
37
+ # 라벨 매핑 저장
38
+ self.id2label = config.id2label
39
+ self.num_classes = config.num_labels
40
+
41
+ # 벡터라이저의 특성 정보를 텐서로 저장
42
+ self.register_buffer('feature_names_list', torch.tensor([hash(f) for f in self.feature_names], dtype=torch.long))
43
 
44
  def forward(self, input_ids=None, attention_mask=None, labels=None, **kwargs):
45
+ """통합 forward"""
46
+ # XLM-RoBERTa 출력
47
  if input_ids is not None:
48
+ xlm_outputs = self.xlm_roberta(
49
+ input_ids=input_ids,
50
+ attention_mask=attention_mask,
51
+ return_dict=True
52
+ )
53
+ xlm_features = xlm_outputs.pooler_output
 
 
54
  else:
55
+ xlm_features = torch.zeros(1, self.xlm_roberta.config.hidden_size)
 
56
 
57
+ # TF-IDF 벡터화 (내부적으로 수행)
58
+ if input_ids is not None:
59
+ # input_ids를 텍스트로 변환하여 TF-IDF 벡터화
60
+ text_vector = self._vectorize_from_ids(input_ids[0])
61
+ tfidf_features = torch.FloatTensor(text_vector).unsqueeze(0)
62
+ else:
63
+ tfidf_features = torch.zeros(1, self.input_size)
64
+
65
+ # 신경망 통과 (TF-IDF 부분만 사용)
66
+ x = F.relu(self.fc1(tfidf_features))
67
  x = self.dropout(x)
68
  x = F.relu(self.fc2(x))
69
  x = self.dropout(x)
 
77
 
78
  return {"loss": loss, "logits": logits} if loss is not None else {"logits": logits}
79
 
80
+ def _vectorize_from_ids(self, input_ids):
81
+ """input_ids를 TF-IDF 벡터로 변환"""
82
+ vector = np.zeros(self.input_size)
83
+
84
  # input_ids를 기반으로 벡터 생성
85
  for token_id in input_ids:
86
+ if token_id < self.input_size:
87
  vector[token_id] += 1
88
 
89
  if np.sum(vector) > 0:
 
103
  with open(config_path, 'r', encoding='utf-8') as f:
104
  config_data = json.load(f)
105
 
106
+ # XLMSteelConfig 생성
107
+ config = XLMSteelConfig(
 
 
 
108
  num_labels=config_data['num_labels'],
109
  id2label=config_data['id2label'],
110
+ label2id=config_data['label2id'],
111
+ feature_names=config_data.get('feature_names', []),
112
+ input_size=config_data.get('input_size', 3000)
113
  )
114
 
115
  # 모델 생성 및 로드
116
+ model = XLMIntegratedModel(config)
117
+ model_path = os.path.join(os.getcwd(), "xlm_integrated_model.bin")
118
  model.load_state_dict(torch.load(model_path, map_location='cpu'))
119
  model.eval()
120
 
 
136
  else:
137
  text = str(inputs)
138
 
139
+ # 텍스트를 토큰 ID로 변환 (간단한 구현)
140
  tokens = text.lower().split()
141
+ input_ids = torch.tensor([[hash(token) % 50000 for token in tokens]]) # XLM-RoBERTa vocab size
142
+ attention_mask = torch.ones_like(input_ids)
143
 
144
  # 예측
145
  with torch.no_grad():
146
+ outputs = model(input_ids=input_ids, attention_mask=attention_mask)
147
  logits = outputs["logits"]
148
  probabilities = F.softmax(logits, dim=1)
149
  predicted_class = torch.argmax(probabilities, dim=1).item()