cnp-ai commited on
Commit
b361710
·
verified ·
1 Parent(s): a744321

Upload 24 files

Browse files
Files changed (25) hide show
  1. .gitattributes +4 -0
  2. README.md +6 -6
  3. app.py +496 -0
  4. chroma_NCS_241230/chroma.sqlite3 +3 -0
  5. chroma_NCS_241230/ebccdbbe-758c-4b8f-a83d-ff693ed6136e/data_level0.bin +3 -0
  6. chroma_NCS_241230/ebccdbbe-758c-4b8f-a83d-ff693ed6136e/header.bin +3 -0
  7. chroma_NCS_241230/ebccdbbe-758c-4b8f-a83d-ff693ed6136e/index_metadata.pickle +3 -0
  8. chroma_NCS_241230/ebccdbbe-758c-4b8f-a83d-ff693ed6136e/length.bin +3 -0
  9. chroma_NCS_241230/ebccdbbe-758c-4b8f-a83d-ff693ed6136e/link_lists.bin +3 -0
  10. chroma_kpi_250416/9d0a85b6-70fd-4f2e-9365-fd30d7d39b3f/data_level0.bin +3 -0
  11. chroma_kpi_250416/9d0a85b6-70fd-4f2e-9365-fd30d7d39b3f/header.bin +3 -0
  12. chroma_kpi_250416/9d0a85b6-70fd-4f2e-9365-fd30d7d39b3f/index_metadata.pickle +3 -0
  13. chroma_kpi_250416/9d0a85b6-70fd-4f2e-9365-fd30d7d39b3f/length.bin +3 -0
  14. chroma_kpi_250416/9d0a85b6-70fd-4f2e-9365-fd30d7d39b3f/link_lists.bin +3 -0
  15. chroma_kpi_250416/chroma.sqlite3 +3 -0
  16. chroma_kpi_250528_SBERT/4d649a70-b1cb-4039-90e2-3e333c58b8d5/data_level0.bin +3 -0
  17. chroma_kpi_250528_SBERT/4d649a70-b1cb-4039-90e2-3e333c58b8d5/header.bin +3 -0
  18. chroma_kpi_250528_SBERT/4d649a70-b1cb-4039-90e2-3e333c58b8d5/index_metadata.pickle +3 -0
  19. chroma_kpi_250528_SBERT/4d649a70-b1cb-4039-90e2-3e333c58b8d5/length.bin +3 -0
  20. chroma_kpi_250528_SBERT/4d649a70-b1cb-4039-90e2-3e333c58b8d5/link_lists.bin +3 -0
  21. chroma_kpi_250528_SBERT/chroma.sqlite3 +3 -0
  22. chroma_kpi_250707_SBERTjhgan/8022c180-484c-40e6-8793-a686ab1771e8/index_metadata.pickle +3 -0
  23. chroma_kpi_250707_SBERTjhgan/chroma.sqlite3 +3 -0
  24. requirements.txt +12 -0
  25. template.xlsx +0 -0
.gitattributes CHANGED
@@ -33,3 +33,7 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ chroma_kpi_250416/chroma.sqlite3 filter=lfs diff=lfs merge=lfs -text
37
+ chroma_kpi_250528_SBERT/chroma.sqlite3 filter=lfs diff=lfs merge=lfs -text
38
+ chroma_kpi_250707_SBERTjhgan/chroma.sqlite3 filter=lfs diff=lfs merge=lfs -text
39
+ chroma_NCS_241230/chroma.sqlite3 filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -1,12 +1,12 @@
1
  ---
2
- title: Kpi Search
3
- emoji: 👁
4
- colorFrom: yellow
5
- colorTo: purple
6
  sdk: gradio
7
- sdk_version: 5.35.0
8
  app_file: app.py
9
  pinned: false
10
  ---
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: KPI POOL 검색
3
+ emoji: 🏃
4
+ colorFrom: blue
5
+ colorTo: indigo
6
  sdk: gradio
7
+ sdk_version: 5.31.0
8
  app_file: app.py
9
  pinned: false
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py ADDED
@@ -0,0 +1,496 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain_chroma import Chroma
2
+ from langchain_huggingface import HuggingFaceEmbeddings
3
+ from sentence_transformers import SentenceTransformer
4
+ from sklearn.metrics.pairwise import cosine_similarity
5
+ from openpyxl import load_workbook
6
+ import pandas as pd
7
+ import gradio as gr
8
+ import numpy as np
9
+ import re
10
+
11
+ # Chroma DB 로드
12
+ ###기본(BGE)
13
+ model_huggingface_ori = HuggingFaceEmbeddings(model_name='BAAI/bge-m3')
14
+ persist_directory_ori = './chroma_kpi_250416'
15
+ kpi_pool_ori = Chroma(persist_directory=persist_directory_ori, embedding_function=model_huggingface_ori)
16
+ print(kpi_pool_ori._collection.count())
17
+
18
+ persist_directory_ori2 = './chroma_ncs_241230'
19
+ ncs_db_ori = Chroma(persist_directory=persist_directory_ori2, embedding_function=model_huggingface_ori)
20
+ print(ncs_db_ori._collection.count())
21
+
22
+ ###
23
+
24
+ model_huggingface = HuggingFaceEmbeddings(model_name='snunlp/KR-SBERT-V40K-klueNLI-augSTS')
25
+ persist_directory1 = './chroma_kpi_250528_SBERT'
26
+ kpi_pool = Chroma(persist_directory=persist_directory1, embedding_function=model_huggingface)
27
+ print(kpi_pool._collection.count())
28
+
29
+ ####
30
+
31
+ model_huggingface2 = HuggingFaceEmbeddings(model_name='jhgan/ko-sbert-sts')
32
+ persist_directory_jhgan1 = './chroma_kpi_250707_SBERTjhgan'
33
+ kpi_pool2 = Chroma(persist_directory=persist_directory_jhgan1, embedding_function=model_huggingface2)
34
+ print(kpi_pool2._collection.count())
35
+
36
+
37
+ def search_unit(unit_query):
38
+ results = ncs_db_ori.similarity_search_with_relevance_scores(unit_query, k=7)
39
+
40
+ # 검색 결과 텍스트 포맷팅
41
+ text = ""
42
+ for i, doc in enumerate(results):
43
+ # 텍스트와 메타데이터 처리
44
+ unit = doc[0].page_content.replace(", ", "  /  ")
45
+ job_name = doc[0].metadata['세분류코드명']
46
+
47
+ # 코드 계층 처리
48
+ code = [
49
+ doc[0].metadata['대분류코드명'],
50
+ doc[0].metadata['중분류코드명'],
51
+ doc[0].metadata['소분류코드명']
52
+ ]
53
+ code_str = " > ".join(code)
54
+
55
+ # 텍스트 포맷팅
56
+ similarity = round(doc[1], 3)
57
+ text += f"""
58
+ <span style="font-size: 18px;">**[{i+1}] {job_name}**</span>
59
+ <span style="font-size: 13px;"> &nbsp; | &nbsp; {code_str} &nbsp; | &nbsp; similarity {similarity} </span>
60
+ <br> {unit} <br>
61
+ """
62
+ return text
63
+
64
+ def search_unit_all(unit_query):
65
+ text_bge = search_unit(unit_query, "BGE")
66
+ text_snu = search_unit(unit_query, "SBERT-snunlp")
67
+ #text_jh = search_unit(unit_query, "SBERT-jhgan")
68
+
69
+ return text_bge, text_snu
70
+
71
+ downsample_model_ori = SentenceTransformer('BAAI/bge-m3')
72
+ downsample_model = SentenceTransformer('snunlp/KR-SBERT-V40K-klueNLI-augSTS')
73
+ downsample_model_2 = SentenceTransformer('jhgan/ko-sbert-sts')
74
+
75
+ def filter_semantically_similar_texts_by_embedding(df, mode, embedding_field='embedding_input', similarity_threshold=0.8):
76
+ texts = df[embedding_field].tolist()
77
+
78
+ # 텍스트를 임베딩
79
+ if mode == "BGE":
80
+ embeddings = downsample_model_ori.encode(texts)
81
+ elif mode == "SBERT-snunlp":
82
+ embeddings = downsample_model.encode(texts)
83
+ else:
84
+ embeddings = downsample_model_2.encode(texts)
85
+
86
+ # 코사인 유사도 행렬 계산
87
+ similarity_matrix = cosine_similarity(embeddings)
88
+ np.fill_diagonal(similarity_matrix, 0)
89
+
90
+ # 유사도가 threshold 이상인 항목 필터링
91
+ filtered_indices = []
92
+ excluded_indices = set()
93
+
94
+ for i in range(len(texts)):
95
+ if i not in excluded_indices:
96
+ filtered_indices.append(i)
97
+ similar_indices = np.where(similarity_matrix[i] > similarity_threshold)[0]
98
+ excluded_indices.update(similar_indices)
99
+
100
+ return df.iloc[filtered_indices].reset_index(drop=True)
101
+
102
+
103
+ def search_kpi(kpi_query, kpi_count, mode):
104
+ if mode == "BGE":
105
+ print("BGE 검색 시작")
106
+ results = kpi_pool_ori.similarity_search_with_relevance_scores(kpi_query, k=50)
107
+ elif mode == "SBERT-snunlp":
108
+ print("SBERT-snunlp 검색 시작")
109
+ results = kpi_pool.similarity_search_with_relevance_scores(kpi_query, k=50)
110
+ else:
111
+ print("SBERT-jhgan 검색 시작")
112
+ results = kpi_pool2.similarity_search_with_relevance_scores(kpi_query, k=50)
113
+
114
+
115
+ # 메타데이터 + 점수 추출
116
+ records = [
117
+ {**doc.metadata, '유사도점수': score}
118
+ for doc, score in results
119
+ ]
120
+
121
+ # DataFrame으로 변환
122
+ df = pd.DataFrame(records)
123
+ df['카테고리'] = df['BSC 관점'] + " > " + df['전략방향']
124
+ df = df.drop_duplicates(subset=['정의', '산식']).head(15)
125
+ df = df.iloc[:kpi_count]
126
+ df = df.reset_index(drop=True)
127
+
128
+ # 카테고리 생성 (BSC 관점 + 전략방향)
129
+ df['카테고리'] = df['BSC 관점'] + " > " + df['전략방향']
130
+ visible_df = df[['지표명', '산식', '비고', '카테고리']].copy()
131
+ kpi_list = list(range(1, len(visible_df) + 1))
132
+ kpi_df = df[['지표명', '정의', '산식', '유형', '비고', 'BSC 관점', '전략방향', '전략과제']].copy()
133
+
134
+ return gr.update(visible=True), gr.update(choices=kpi_list), visible_df, kpi_df, kpi_list, gr.update(visible=False)
135
+
136
+ def search_kpi_one(kpi_query, kpi_count, mode):
137
+ if mode == "BGE":
138
+ print("BGE 검색 시작")
139
+ results = kpi_pool_ori.similarity_search_with_relevance_scores(kpi_query, k=50)
140
+ elif mode == "SBERT-snunlp":
141
+ print("SBERT-snunlp 검색 시작")
142
+ results = kpi_pool.similarity_search_with_relevance_scores(kpi_query, k=50)
143
+ else:
144
+ print("SBERT-jhgan 검색 시작")
145
+ results = kpi_pool2.similarity_search_with_relevance_scores(kpi_query, k=50)
146
+
147
+ # 메타데이터 + 점수 추출
148
+ records = [
149
+ {**doc.metadata, '유사도점수': score}
150
+ for doc, score in results
151
+ ]
152
+
153
+ # DataFrame으로 변환
154
+ df = pd.DataFrame(records)
155
+ df['카테고리'] = df['BSC 관점'] + " > " + df['전략방향']
156
+ df = df.drop_duplicates(subset=['정의', '산식']).head(15)
157
+ df = df.iloc[:kpi_count]
158
+ df = df.reset_index(drop=True)
159
+
160
+ # 카테고리 생성 (BSC 관점 + 전략방향)
161
+ df['카테고리'] = df['BSC 관점'] + " > " + df['전략방향']
162
+ visible_df = df[['지표명', '산식', '비고']].copy()
163
+ kpi_list = list(range(1, len(visible_df) + 1))
164
+ kpi_df = df[['지표명', '정의', '산식', '유형', '비고', 'BSC 관점', '전략방향', '전략과제']].copy()
165
+
166
+ return visible_df, kpi_df, kpi_list
167
+
168
+ def format_df_html(df):
169
+ html = ""
170
+ for i, row in df.iterrows():
171
+ html += f"""
172
+ <div style="margin-bottom: 5px;">
173
+ <span style="font-size: 18px; font-weight: bold;">[{i+1}] {row['지표명']}</span><br>
174
+ <span style="font-size: 13px; color: gray;">{row['비고']}</span><br>
175
+ <div style="margin-top: 5px; font-size: 14px; color: #333;">{row['산식']}
176
+ </div>
177
+ <div style="height: 8px;"></div>
178
+ </div>
179
+ """
180
+ return html
181
+
182
+ def search_kpi_all_models(kpi_query, kpi_count):
183
+ print("함수 호출, 테이블 생성 시작")
184
+ # 각 모델별 결과
185
+ visible_bge, kpi_bge, list_bge = search_kpi_one(kpi_query, kpi_count, "BGE")
186
+ visible_sn, kpi_sn, list_sn = search_kpi_one(kpi_query, kpi_count, "SBERT-snunlp")
187
+ visible_jh, kpi_jh, list_jh = search_kpi_one(kpi_query, kpi_count, "SBERT-jhgan")
188
+ print("함수 종료")
189
+
190
+ visible_df = [visible_bge, visible_sn, visible_jh]
191
+ visible_df_text = [format_df_html(df) for df in visible_df]
192
+
193
+ #gr.update(visible=True), gr.update(choices=kpi_list), visible_df, kpi_df, kpi_list, gr.update(visible=False)
194
+
195
+ return (
196
+ gr.update(visible=True),
197
+ gr.update(choices=list_bge), #체크박스리스트
198
+ gr.update(choices=list_sn),
199
+ gr.update(choices=list_jh),
200
+ visible_df_text[0], # kpi_table1
201
+ visible_df_text[1], # kpi_table2
202
+ visible_df_text[2], # kpi_table3
203
+ kpi_bge, kpi_sn, kpi_jh,
204
+ list_bge, list_sn, list_jh,
205
+ gr.update(visible=False)
206
+ )
207
+
208
+
209
+
210
+ # 셀 주소와 값을 매핑한 딕셔너리 생성
211
+ def make_excel_table(dataframe, start_cell):
212
+ table_dict = {}
213
+
214
+ # 시작 셀 좌표 계산
215
+ start_row = int(''.join(filter(str.isdigit, start_cell))) # 시작 행 (숫자)
216
+ start_col = ord(start_cell[0].upper()) - ord('A') + 1 # 시작 열 (문자 -> 숫자)
217
+
218
+ # 데이터프레임 반복 처리
219
+ for row_index, row in enumerate(dataframe.itertuples(index=False), start=start_row):
220
+ for col_index, value in enumerate(row, start=start_col):
221
+ # 셀 주소 계산 (예: B5, C5, ...)
222
+ cell = f"{chr(ord('A') + col_index - 1)}{row_index}"
223
+ table_dict[cell] = value
224
+
225
+ return table_dict
226
+
227
+
228
+ # 다운로드 파일 생성 함수
229
+ def generate_excel(df1, df2, df3, kpi_list1, kpi_list2, kpi_list3, kpi_query):
230
+ #각 모델별 filtered_df 생성
231
+ def get_filtered(df, kpi_list, model_name):
232
+ if kpi_list:
233
+ indices = [int(i) - 1 for i in kpi_list] # -1 보정
234
+ filtered = df.iloc[indices].copy()
235
+ filtered["출처"] = model_name
236
+ return filtered
237
+ else:
238
+ # 선택된 KPI 없을 때: 빈 DataFrame 반환
239
+ return pd.DataFrame(columns=list(df.columns) + ["출처"])
240
+
241
+ # 인덱스(-1 보정)로 DataFrame 필터링
242
+ #filtered_df = df.iloc[[int(i) - 1 for i in kpi_list]] if kpi_list else pd.DataFrame(columns=df.columns)
243
+ filtered_df1 = get_filtered(df1, kpi_list1, "BGE3")
244
+ filtered_df2 = get_filtered(df2, kpi_list2, "snunlp")
245
+ filtered_df3 = get_filtered(df3, kpi_list3, "jhgan")
246
+
247
+ filtered_df = pd.concat([filtered_df1, filtered_df2, filtered_df3], ignore_index=True) #필터링내용 병합
248
+ filtered_df = filtered_df.drop_duplicates(subset='산식') # '산식' 기준 중복 제거
249
+
250
+ # 엑셀 파일 열기
251
+ file_path = "./template.xlsx"
252
+ workbook = load_workbook(file_path)
253
+ sheet = workbook.active
254
+
255
+ update_values = make_excel_table(filtered_df, 'B4')
256
+ for cell, value in update_values.items():
257
+ sheet[cell].value = value
258
+
259
+ # 워크시트 기본 확대 수준 설정(%)
260
+ sheet.sheet_view.zoomScaleNormal = 85
261
+
262
+ # 파일 저장
263
+
264
+ filename = f"KPI_POOL_{kpi_query}.xlsx"
265
+
266
+ safe_filename = re.sub(r'\s*/\s*', '_', filename)
267
+ safe_filename = re.sub(r'\s+', ' ', safe_filename)
268
+ output_file = safe_filename.strip()
269
+
270
+ workbook.save(output_file)
271
+
272
+ return gr.update(value=output_file, visible=True)
273
+
274
+ def toggle_selection(current_selection, kpi_list):
275
+ if set(current_selection) == set(kpi_list): # 이미 전체 선택된 경우
276
+ return []
277
+ else: # 전체 선택 안 된 경우
278
+ return kpi_list
279
+
280
+ def toggle_all_selections(sel1, list1, sel2, list2, sel3, list3):
281
+ def toggle(current, full_list):
282
+ return [] if set(current) == set(full_list) else full_list
283
+
284
+ return (
285
+ toggle(sel1, list1),
286
+ toggle(sel2, list2),
287
+ toggle(sel3, list3)
288
+ )
289
+
290
+ css = """
291
+ /* 데이터프레임 스타일 */
292
+ .gradio-container table {
293
+ table-layout: fixed;
294
+ width: 100%;
295
+ }
296
+ .gradio-container td{
297
+ white-space: nowrap !important;
298
+ overflow-x: auto !important;
299
+ text-align: left;
300
+ font-size: 13px;
301
+ letter-spacing: -1px !important;
302
+ }
303
+ /* 헤더 기본 스타일 */
304
+ .gradio-container th[aria-sort]::after {
305
+ visibility: hidden !important; /* 아이콘만 감춤 */
306
+ }
307
+ .gradio-container th .header-content {
308
+ justify-content: center !important;
309
+ text-align: center;
310
+ font-size: 13px;
311
+ letter-spacing: -1px !important;
312
+ }
313
+ .gradio-container th span {
314
+ text-align: center !important;
315
+ display: block !important;
316
+ width: 100%;
317
+ }
318
+ .v_check { padding-top: 39px !important;
319
+ margin-right: 0px !important;
320
+ padding-right: 0px !important;
321
+ margin-left: 0px !important;
322
+ padding-left: 0px !important;
323
+ }
324
+ .v_check div { display: block !important; }
325
+ .v_check label {
326
+ max-width: 80%; /* 전체 너비 유지 */
327
+ padding: 2px; /* 내부 여백 조정 */
328
+ margin-bottom: 52px; /* 라벨 간 간격 설정 */
329
+ border: 1px solid transparent !important;
330
+ letter-spacing: -1px !important; /* 자간 좁게 설정*/
331
+ justify-content: center;
332
+ }
333
+ div.svelte-1nguped {
334
+ background: transparent !important;
335
+ border: none !important;
336
+ }
337
+
338
+ .left-padding { padding-left: 43px !important; /* 왼쪽 패딩 추가 */ }
339
+
340
+ .custom-markdown h3 {
341
+ font-size: 18px; /* 본문 및 목록 글자 크기 */
342
+ }
343
+ .custom-markdown blockquote {
344
+ margin-bottom: 8px !important;
345
+ }
346
+ .custom-markdown p, .custom-markdown li {
347
+ margin-top: 8px !important;
348
+ font-size: 15px; /* 본문 및 목록 글자 크기 */
349
+ line-height: 1.5;
350
+ }
351
+ .custom-markdown a {
352
+ font-size: 15px;
353
+ color: #000000;
354
+ }
355
+
356
+ .no-margine {
357
+ margin-bottom: 0px !important;
358
+ padding-bottom: 0px !important;
359
+ margin-top: 0px !important;
360
+ padding-top: 0px !important;
361
+ gap: 0px !important;
362
+ }
363
+
364
+
365
+ """
366
+
367
+ guide = """> ### 저작권 및 유의사항 안내
368
+ - 본 앱은 시앤피컨설팅이 개발한 KPI POOL 검색 도구로, AI 기반 추천 결과는 참고용으로 제공됩니다.
369
+ - AI 기반 추천 알고리즘은 전문 컨설팅을 대체할 수 없으며, 반드시 조직의 전략, 평가 목적, 데이터 수집 가능성 등과의 적합성 검토가 필요합니다.
370
+ - KPI 설정과 적용에 대한 개별 맞춤 검토는 시앤피컨설팅의 전문 컨설턴트에게 문의해 주세요.
371
+ <br><br>
372
+ > ### Contact Us
373
+ 시앤피컨설팅그룹 일터혁신본부  |  Tel. 02-6257-1448  |  http://www.cnp.re.kr  |  hpw@cnp.re.kr
374
+ """
375
+
376
+ empty_df = pd.DataFrame(columns=["지표명", "산식", "비고", "카테고리"])
377
+
378
+ with gr.Blocks(css=css, fill_width=True) as demo:
379
+
380
+ df_state1 = gr.State()
381
+ df_state2 = gr.State()
382
+ df_state3 = gr.State()
383
+ check_state1 = gr.State()
384
+ check_state2 = gr.State()
385
+ check_state3 = gr.State()
386
+
387
+ with gr.Row():
388
+ #mode = gr.Dropdown(choices={"BGE","SBERT-snunlp","SBERT-jhgan"}, label="모델을 선택하세요")
389
+ gr.Markdown(" ")
390
+ with gr.Tab("KPI Pool 검색"):
391
+ with gr.Column(elem_classes="left-padding"):
392
+ with gr.Row(equal_height=True):
393
+ kpi_query = gr.Textbox(scale=30, submit_btn=True,
394
+ label= "성과평가를 진행할 [핵심업무 or 핵심성공요인]을 입력해주세요😊! (검색 키워드는 직무기술서 또는 NCS 능력단위 참고)",
395
+ placeholder="예: 자금 → 자금조달 / 재무위험관리 / 자금운용")
396
+ kpi_count = gr.Slider(label="KPI 출력 개수", value = 7, minimum=5, maximum=10, step=1, scale=7)
397
+
398
+ copyright = gr.Markdown(guide, visible=True, elem_classes="custom-markdown")
399
+
400
+ with gr.Column(visible=False) as output_area:
401
+ with gr.Group():
402
+ with gr.Row():
403
+ with gr.Group():
404
+ with gr.Tab("BAAI"):
405
+ with gr.Row():
406
+ kpi_checkbox1 = gr.CheckboxGroup(choices=[], interactive=True, elem_classes="v_check", container=False, min_width=5, scale=1)
407
+ with gr.Column(scale=11):
408
+ kpi_table1 = gr.HTML(label="BGE 결과")
409
+
410
+ with gr.Group():
411
+ with gr.Tab("snunlp"):
412
+ with gr.Row():
413
+ kpi_checkbox2 = gr.CheckboxGroup(choices=[], interactive=True, elem_classes="v_check", container=False, min_width=5, scale=1)
414
+ with gr.Column(scale=11):
415
+ kpi_table2 = gr.HTML(label="SBERT-snunlp 결과")
416
+
417
+ with gr.Group():
418
+ with gr.Tab("jhgan"):
419
+ with gr.Row():
420
+ kpi_checkbox3 = gr.CheckboxGroup(choices=[], interactive=True, elem_classes="v_check", container=False, min_width=5, scale=1)
421
+ with gr.Column(scale=11):
422
+ kpi_table3 = gr.HTML(label="SBERT-jhgan 결과")
423
+ with gr.Row():
424
+ gr.Column(scale=2)
425
+ select_button = gr.Button("All", scale=1)
426
+ download_button = gr.Button("Download",scale=1)
427
+ clear_button = gr.Button("Clear",scale=1)
428
+ gr.Column(scale=2)
429
+
430
+ file_download = gr.Files(label="Download", interactive=False, visible=False)
431
+
432
+ #kpi_query.submit(search_kpi, inputs = [kpi_query, kpi_count, mode], outputs = [output_area, kpi_checkbox, kpi_table, df_state, check_state, copyright])
433
+ kpi_query.submit(
434
+ search_kpi_all_models,
435
+ inputs = [kpi_query, kpi_count],
436
+ outputs = [
437
+ output_area,
438
+ kpi_checkbox1, kpi_checkbox2, kpi_checkbox3,
439
+ kpi_table1, kpi_table2, kpi_table3,
440
+ df_state1, df_state2, df_state3,
441
+ check_state1,check_state2,check_state3,
442
+ copyright
443
+ ]
444
+ )
445
+
446
+ #select_button.click(fn=toggle_selection, inputs=[kpi_checkbox, check_state], outputs=kpi_checkbox, show_progress='hidden')
447
+ select_button.click(
448
+ fn=toggle_all_selections,
449
+ inputs=[
450
+ kpi_checkbox1, check_state1,
451
+ kpi_checkbox2, check_state2,
452
+ kpi_checkbox3, check_state3
453
+ ],
454
+ outputs=[
455
+ kpi_checkbox1,
456
+ kpi_checkbox2,
457
+ kpi_checkbox3
458
+ ],
459
+ show_progress='hidden'
460
+ )
461
+
462
+ download_button.click(
463
+ generate_excel,
464
+ inputs=[df_state1, df_state2, df_state3, kpi_checkbox1, kpi_checkbox2, kpi_checkbox3, kpi_query],
465
+ outputs=[file_download]
466
+ )
467
+
468
+ clear_button.click(
469
+ fn=lambda: (None, None, None,
470
+ None, gr.update(visible=False),
471
+ gr.update(choices=[], value=[]),gr.update(choices=[], value=[]),gr.update(choices=[], value=[]),
472
+ gr.update(value=""),gr.update(value=""),gr.update(value=""),
473
+ gr.update(value=None, visible=False), gr.update(visible=True)),
474
+ outputs=[df_state1, df_state2, df_state3,
475
+ kpi_query, output_area,
476
+ kpi_checkbox1, kpi_checkbox2, kpi_checkbox3,
477
+ kpi_table1, kpi_table2, kpi_table3,
478
+ file_download, copyright],
479
+ show_progress='hidden'
480
+ )
481
+
482
+
483
+ with gr.Tab("[참고] NCS 능력단위"):
484
+ unit_query = gr.Textbox(label="업종 or 직종 + 직무명을 입력하세요😊", scale=1, submit_btn=True,
485
+ placeholder="예: 의약품 법률자문, 공공행정 경영기획, 재무회계 자금")
486
+ with gr.Row():
487
+ with gr.Group():
488
+ unit_result = gr.Markdown()
489
+ #with gr.Group():
490
+ # with gr.Tab("SBERT-snunlp"):
491
+ # unit_result2 = gr.Markdown()
492
+
493
+ unit_query.submit(search_unit, inputs=[unit_query], outputs=[unit_result])
494
+ #unit_query.submit(search_unit_all, inputs=unit_query, outputs=[unit_result1, unit_result2])
495
+
496
+ demo.launch(debug=True)
chroma_NCS_241230/chroma.sqlite3 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c72fb31a891a48edb728e5843dba0ef6770ee980090040fa8f72addfe8c493e3
3
+ size 31084544
chroma_NCS_241230/ebccdbbe-758c-4b8f-a83d-ff693ed6136e/data_level0.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fd3a5a9831d1617ac3e7598c27ba553147e576ec71eba5853cc055a727129939
3
+ size 4236000
chroma_NCS_241230/ebccdbbe-758c-4b8f-a83d-ff693ed6136e/header.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:378ffc4871c60c0d0445551b475a2b05d6ffb148da26058c23a985b3b555b647
3
+ size 100
chroma_NCS_241230/ebccdbbe-758c-4b8f-a83d-ff693ed6136e/index_metadata.pickle ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:11c25b3d3fce8262cdb533218b1417b19348543934e829abb1e9397a02cebaff
3
+ size 55952
chroma_NCS_241230/ebccdbbe-758c-4b8f-a83d-ff693ed6136e/length.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e14c6fe19326be985cdecde2aea3c3b97db912467f86226ec356324b267547cb
3
+ size 4000
chroma_NCS_241230/ebccdbbe-758c-4b8f-a83d-ff693ed6136e/link_lists.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d4d8434b65f48bb9e57b942d930b40350450ca71ad6d8e747967f0ddba421bbb
3
+ size 8420
chroma_kpi_250416/9d0a85b6-70fd-4f2e-9365-fd30d7d39b3f/data_level0.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a9f0db303c11076ee583b209870a5d0fecca706dbcbbeecf2f79075c5e03b4b7
3
+ size 16944000
chroma_kpi_250416/9d0a85b6-70fd-4f2e-9365-fd30d7d39b3f/header.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3f3cc826c2c7868c474a8118077c214b271742a653835ccc9272e81b0110060b
3
+ size 100
chroma_kpi_250416/9d0a85b6-70fd-4f2e-9365-fd30d7d39b3f/index_metadata.pickle ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7e76bcc13eb22a154d420b338a7c2a0b173dc701a30dceaf473ddbd9702aab3e
3
+ size 229997
chroma_kpi_250416/9d0a85b6-70fd-4f2e-9365-fd30d7d39b3f/length.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ecf55833a7fbf8155dd1c4cb95ce88ac4a867c237d37a3336a1918600e127231
3
+ size 16000
chroma_kpi_250416/9d0a85b6-70fd-4f2e-9365-fd30d7d39b3f/link_lists.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2798bf29180b7286df84096e1af8903fddc00d78f6669f0c3f9f680514deb668
3
+ size 34836
chroma_kpi_250416/chroma.sqlite3 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c01587f00d4291b0e13891e1a9deb842dfca081a1eaf1f4be664170b9af3c881
3
+ size 43872256
chroma_kpi_250528_SBERT/4d649a70-b1cb-4039-90e2-3e333c58b8d5/data_level0.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:82c055ad7c5550f6c251f61b19ba1505be21a164d1e1f251ebaacff9f6855835
3
+ size 32120000
chroma_kpi_250528_SBERT/4d649a70-b1cb-4039-90e2-3e333c58b8d5/header.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a99decffb1a7dd32ffa29cbdbe273fd8bd6f7452a14f70c8132b82afe79f9549
3
+ size 100
chroma_kpi_250528_SBERT/4d649a70-b1cb-4039-90e2-3e333c58b8d5/index_metadata.pickle ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f69a59ab337882aae5b2b09d2dce571af72e20bbf9f7df1ac55357398f31e7ea
3
+ size 455084
chroma_kpi_250528_SBERT/4d649a70-b1cb-4039-90e2-3e333c58b8d5/length.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e7e2dcff542de95352682dc186432e98f0188084896773f1973276b0577d5305
3
+ size 40000
chroma_kpi_250528_SBERT/4d649a70-b1cb-4039-90e2-3e333c58b8d5/link_lists.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d015ab2c51ea08a92cf04aee17ecc291a6285ac58b24168755315cd8d651a218
3
+ size 44192
chroma_kpi_250528_SBERT/chroma.sqlite3 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1bfcda17dab8c96c058d9ff96dc7b26874d14d2bfbf647627fec2b8afab87c3d
3
+ size 35680256
chroma_kpi_250707_SBERTjhgan/8022c180-484c-40e6-8793-a686ab1771e8/index_metadata.pickle ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:96e1a9d07ddd694d951fc1ebe2d7ccd1d717ac6e5eee776e7f2d9746c49ca034
3
+ size 455084
chroma_kpi_250707_SBERTjhgan/chroma.sqlite3 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:307abb365458b4525914468c8f83951da32d2be2f910d714d43c9363efb6fa98
3
+ size 35676160
requirements.txt ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ chromadb>=0.6.9
2
+ langchain-core>=0.3.52
3
+ langchain-chroma>=0.2.3
4
+ langchain-huggingface>=0.1.2
5
+ sentence-transformers>=3.4.1
6
+ transformers==4.42.4
7
+ gradio
8
+ torch>=2.2.0
9
+ numpy>=1.26.4
10
+ pandas>=2.1.4
11
+ scikit-learn>=1.3.2
12
+ openpyxl==3.1.5
template.xlsx ADDED
Binary file (11.6 kB). View file