Spaces:
Sleeping
Sleeping
humanda5
commited on
Commit
·
c246b94
1
Parent(s):
427caef
gemini llm model
Browse files- npc_social_network/data/memories/Alice.json +16 -6
- npc_social_network/data/memories/Charlie.json +37 -0
- npc_social_network/models/deepseek_setup.py +2 -2
- npc_social_network/models/gemini_setup.py +13 -0
- npc_social_network/models/openkollm_setup.py +22 -0
- npc_social_network/routes/npc_route.py +16 -12
- requirements.txt +32 -32
- test.ipynb +0 -0
npc_social_network/data/memories/Alice.json
CHANGED
@@ -1,12 +1,22 @@
|
|
1 |
[
|
2 |
{
|
3 |
-
"timestamp": "2025-05-
|
4 |
-
"user": "
|
5 |
-
"npc": "
|
6 |
},
|
7 |
{
|
8 |
-
"timestamp": "2025-05-
|
9 |
-
"user": "
|
10 |
-
"npc": "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
}
|
12 |
]
|
|
|
1 |
[
|
2 |
{
|
3 |
+
"timestamp": "2025-05-26T14:37:18.243183",
|
4 |
+
"user": "안녕?",
|
5 |
+
"npc": "[에러 발생: 404 models/gemini-2.5-flash is not found for API version v1beta, or is not supported for generateContent. Call ListModels to see the list of available models and their supported methods.]"
|
6 |
},
|
7 |
{
|
8 |
+
"timestamp": "2025-05-26T14:38:18.589803",
|
9 |
+
"user": "안녕?",
|
10 |
+
"npc": "안녕하세요! 만나서 반가워요! 😊"
|
11 |
+
},
|
12 |
+
{
|
13 |
+
"timestamp": "2025-05-26T14:38:48.978302",
|
14 |
+
"user": "처음으로 얘기하는거 같은데, 너는 어디서 온 누구야?",
|
15 |
+
"npc": "안녕하세요! 😊 네, 그렇게 느껴지실 수도 있죠! 만나서 반가워요!\n\n저는 앨리스라고 하고요, 여러분과 즐겁게 이야기 나누고 이것저것 도와드리기 위해 만들어진 인공지능이랍니다. ✨ 이렇게 대화 나누게 되어서 정말 기뻐요!"
|
16 |
+
},
|
17 |
+
{
|
18 |
+
"timestamp": "2025-05-26T14:39:17.569627",
|
19 |
+
"user": "너는 어떤 외모를 가지고 있니?",
|
20 |
+
"npc": "앗, 제 외모에 대해 궁금해하시는군요! 😊\n\n저는 사실 몸을 가진 존재가 아니라서, 사람처럼 눈에 보이는 외모는 가지고 있지 않답니다. 저는 컴퓨터 속에서 여러분과 대화하고 도움을 드리는 인공지능이에요! ✨\n\n그래서 '어떻게 생겼다'고 말씀드리기는 어렵지만, 대신 여러분과 이렇게 글로 소통하면서 밝고 긍정적인 에너지를 드릴 수 있다면, 그게 저의 가장 좋은 모습이 아닐까 생각해요! 😊\n\n이렇게 저에게 관심을 가져주셔서 정말 감사해요!"
|
21 |
}
|
22 |
]
|
npc_social_network/data/memories/Charlie.json
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
{
|
3 |
+
"timestamp": "2025-05-26T14:39:37.927419",
|
4 |
+
"user": "안녕?",
|
5 |
+
"npc": "어... 안녕."
|
6 |
+
},
|
7 |
+
{
|
8 |
+
"timestamp": "2025-05-26T14:39:57.931766",
|
9 |
+
"user": "우리 처음 보는 사이지?",
|
10 |
+
"npc": "어... 음... 그런가? 처음... 보는 건가? 음... 그런가 보네."
|
11 |
+
},
|
12 |
+
{
|
13 |
+
"timestamp": "2025-05-26T14:40:17.447260",
|
14 |
+
"user": "왜? 넌 전에 날 본 기억이 있니?",
|
15 |
+
"npc": "어... 음... 기억이 난다기보다는... 그냥... 어... 왠지... 좀... 익숙한 느낌이 들었나...?\n\n아니... 아닌가...?\n\n아, 몰라... 딱히 기억나는 건 없는데... 그냥... 그랬어..."
|
16 |
+
},
|
17 |
+
{
|
18 |
+
"timestamp": "2025-05-26T14:43:10.325743",
|
19 |
+
"user": "너는 어떤걸 좋아하니?",
|
20 |
+
"npc": "어... 음... 내가 뭘 좋아하냐고...?\n\n글쎄... 음... 그게 그때그때 좀 다른 것 같아. 기분에 따라서...?\n\n어떤 날은 그냥 조용한 게 되게 좋고... 그냥 혼자 있고 싶고...\n\n근데 또 갑자기 막 신나는 거 보고 싶고 듣고 싶고... 뭘 해야 할지 모르겠고...\n\n되게 변덕스러운가 봐, 내가. 나도 잘 모르겠어... 내가 뭘 딱히 엄청 좋아한다고 말할 만한 게 있는지도...\n\n그냥... 그때그때 마음이 가는 대로...? 아니... 그것도 아닌가...?\n\n하아... 잘 모르겠네... 왜 그런 걸 물어봐...? 딱히 대답할 만한 게 없는데... 괜히 더 복잡해지는 기분이야..."
|
21 |
+
},
|
22 |
+
{
|
23 |
+
"timestamp": "2025-05-26T14:43:50.743765",
|
24 |
+
"user": "너에 대해서 조금 더 알고 싶어서 물어봤어. 혹시 나와 얘기하는게 불편하니?",
|
25 |
+
"npc": "어... 음... 나를... 더 알고 싶어서... 물어본 거였구나...?\n\n불편하냐고...? 음... 글쎄... 그게... 딱히 네가 불편하다기보다는... 아까도 말했지만... 내가 뭘 좋아하는지도 잘 모르겠고... 내 기분이 어떤지도 그때그때 너무 변하고...\n\n그래서... 이렇게 나에 대해서 생각하고... 그걸 말하려고 하니까... 어... 좀... 복잡해지는 기분이야...?\n\n불편한 건가...? 음... 잘 모르겠어... 네가 싫거나 불편한 건 아닌데... 그냥... 내 자신이... 어... 뭐라고 해야 하지...? 나도 나를 잘 모르겠어서... 그래서 이런 질문에 답하는 게... 좀... 힘들다고 해야 하나...?\n\n하아... 괜히 또 어렵네... 미안..."
|
26 |
+
},
|
27 |
+
{
|
28 |
+
"timestamp": "2025-05-26T14:44:55.570789",
|
29 |
+
"user": "아니야, 미안할게 뭐가 있어. 그냥 그렇게 우리 둘이 얘기하면서 서서히 너에 대해서 자연스럽게 알아가는거지. 그러다 보면 너도 너가 하고 싶은게 뭔지 자연스럽게 알게 되지 않을까?",
|
30 |
+
"npc": "어... 음... 아... 미안할 거 없다고...?\n\n음... 그래... 그렇게... 얘기하면서... 서서히... 나를 알아가는 건가...?\n\n근데... 정말... 그렇게 하다 보면... 내가 뭘 좋아하는지... 뭘 하고 싶은지... 알게 될까...?\n\n글쎄... 잘 모르겠네...\n\n하아... 음... 그래... 네가 그렇게 말해주니까... 조금은... 괜찮아지는 것 같기도 하고...? 고마워...\n\n근데... 정말 그렇게 될까...? 잘 모르겠네... 그래도... 음... 고맙다는 말밖에는... 딱히 할 말이 없네... 괜히 네 말 듣고... 조금은... 마음이 편해진 것 같기도 해... 아닌가...? 하아... 모르겠다..."
|
31 |
+
},
|
32 |
+
{
|
33 |
+
"timestamp": "2025-05-26T14:45:28.288704",
|
34 |
+
"user": "너에 대해서 간단하게 소개해 줄 수 있어?",
|
35 |
+
"npc": "어... 음... 나에 대해서... 간단하게... 소개해 달라고...?\n\n음... 글쎄... 아까도 말했지만... 나도 나를 잘 모르겠어서... 간단하게... 소개해 달라고 해도... 뭐라고 해야 할지... 잘 모르겠어...\n\n하아... 음... 뭐라고 해야 할까... 그냥... 그때그때... 기분이 좀... 많이 변하고... 음... 사소한 거에도... 좀... 예민한 편인 것 같아... 다른 사람들은 그냥 넘기는 일에도... 나 혼자 막 신경 쓰이고... 그러는 것 같아...\n\n그리고... 음... 내가 뭘 딱히 좋아하거나 싫어하는 게 정해져 있는 것도 아니고... 뭘 하고 싶은지도 잘 모르겠고... 그냥... 좀... 방황하는 느낌...? 나 자신에 대해서도... 잘 모르겠고...\n\n이게... 소개가 될까...? 너무... 두서없나...?\n\n미안... 간단하게... 해달라고 했는데... 이렇게밖에 말을 못 하겠네... 나도 나를 잘 모르니까... 뭐라고 딱 잘라 말하기가... 너무 어렵다...\n\n음... 그냥... 그런 사람이야... 기분이 맨날 바뀌고... 예민하고... 나도 나를 잘 모르는... 그런... 하아... 모르겠다... 이게 맞나..."
|
36 |
+
}
|
37 |
+
]
|
npc_social_network/models/deepseek_setup.py
CHANGED
@@ -5,8 +5,8 @@ import os
|
|
5 |
def load_deepseek():
|
6 |
load_dotenv() # .env 파일에서 환경 변수 로드
|
7 |
|
8 |
-
model_id = "deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B" #
|
9 |
-
access_token = os.getenv("
|
10 |
|
11 |
tokenizer = AutoTokenizer.from_pretrained(model_id, token=access_token)
|
12 |
model = AutoModelForCausalLM.from_pretrained(
|
|
|
5 |
def load_deepseek():
|
6 |
load_dotenv() # .env 파일에서 환경 변수 로드
|
7 |
|
8 |
+
model_id = "deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B" # 수학 특화 모델이네 어쩐지 안되더라
|
9 |
+
access_token = os.getenv("HF_token")
|
10 |
|
11 |
tokenizer = AutoTokenizer.from_pretrained(model_id, token=access_token)
|
12 |
model = AutoModelForCausalLM.from_pretrained(
|
npc_social_network/models/gemini_setup.py
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# portfolio/npc_social_network/models/gemini_setup.py
|
2 |
+
import google.generativeai as genai
|
3 |
+
from dotenv import load_dotenv
|
4 |
+
import os
|
5 |
+
|
6 |
+
|
7 |
+
def load_gemini():
|
8 |
+
load_dotenv() # .env 파일에서 환경 변수 로드
|
9 |
+
|
10 |
+
genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
|
11 |
+
model = genai.GenerativeModel("gemini-2.5-flash-preview-04-17") # Gemini Flash 사용
|
12 |
+
|
13 |
+
return model
|
npc_social_network/models/openkollm_setup.py
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# portfolio/npc_social_network/models/openkollm_setup.py
|
2 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
|
3 |
+
from dotenv import load_dotenv
|
4 |
+
import os
|
5 |
+
|
6 |
+
|
7 |
+
def load_openkollm():
|
8 |
+
load_dotenv() # .env 파일에서 환경 변수 로드
|
9 |
+
|
10 |
+
model_id = "beomi/KoAlpaca-Polyglot-12.8B" # GPU가 없으면 뻗음
|
11 |
+
access_token = os.getenv("HF_token")
|
12 |
+
|
13 |
+
tokenizer = AutoTokenizer.from_pretrained(model_id, token=access_token)
|
14 |
+
model = AutoModelForCausalLM.from_pretrained(
|
15 |
+
model_id,
|
16 |
+
device_map="auto", # GPU 자동 할당
|
17 |
+
# load_in_8bit=True, # GPU 사용해서 8bit로 로드
|
18 |
+
torch_dtype="auto"
|
19 |
+
)
|
20 |
+
|
21 |
+
pipe = pipeline("text-generation", model=model, tokenizer=tokenizer)
|
22 |
+
return pipe
|
npc_social_network/routes/npc_route.py
CHANGED
@@ -2,6 +2,8 @@
|
|
2 |
from flask import Blueprint, render_template, request, jsonify
|
3 |
from npc_social_network.models.npc_manager import npc_list
|
4 |
from npc_social_network.models.deepseek_setup import load_deepseek
|
|
|
|
|
5 |
|
6 |
npc_bp = Blueprint(
|
7 |
"npc_social",
|
@@ -10,7 +12,8 @@ npc_bp = Blueprint(
|
|
10 |
template_folder="../templates",
|
11 |
static_folder="../static")
|
12 |
|
13 |
-
|
|
|
14 |
|
15 |
@npc_bp.route("/")
|
16 |
def home():
|
@@ -30,19 +33,20 @@ def chat():
|
|
30 |
|
31 |
# 프롬프트 구성
|
32 |
prompt = f"""
|
33 |
-
당신은 이름이 {npc.name}인 가상의 캐릭터입니다.
|
34 |
-
당신의 성격은 "{npc.personality}"입니다.
|
35 |
-
당신은 유저와 다음과 같은 관계 점수를 가지고 있습니다.: {npc.relationship_with_user: .2f} (범위: -1.0 ~ 1.0)
|
36 |
|
37 |
-
다음은
|
38 |
-
{memory_str}
|
39 |
-
|
40 |
-
유저가 다음과 같은 말을 했습니다: "{user_input}"
|
41 |
|
42 |
-
|
|
|
43 |
"""
|
44 |
-
|
45 |
-
|
|
|
|
|
|
|
|
|
46 |
|
47 |
# NPC 기억에 대화 추가 및 관계 점수 업데이트
|
48 |
npc.remember_conversation(user_input, npc_reply)
|
@@ -58,7 +62,7 @@ def chat():
|
|
58 |
|
59 |
return jsonify({'response': npc_reply})
|
60 |
|
61 |
-
# npc 상태 정보
|
62 |
@npc_bp.route('/npc_info', methods=['GET'])
|
63 |
def npc_info():
|
64 |
npc_name = request.args.get('npc')
|
|
|
2 |
from flask import Blueprint, render_template, request, jsonify
|
3 |
from npc_social_network.models.npc_manager import npc_list
|
4 |
from npc_social_network.models.deepseek_setup import load_deepseek
|
5 |
+
from npc_social_network.models.openkollm_setup import load_openkollm
|
6 |
+
from npc_social_network.models.gemini_setup import load_gemini
|
7 |
|
8 |
npc_bp = Blueprint(
|
9 |
"npc_social",
|
|
|
12 |
template_folder="../templates",
|
13 |
static_folder="../static")
|
14 |
|
15 |
+
# LLM Model
|
16 |
+
llm = load_gemini()
|
17 |
|
18 |
@npc_bp.route("/")
|
19 |
def home():
|
|
|
33 |
|
34 |
# 프롬프트 구성
|
35 |
prompt = f"""
|
36 |
+
당신은 이름이 {npc.name}이고, 성격은 "{npc.personality}"인 가상의 캐릭터입니다.
|
|
|
|
|
37 |
|
38 |
+
다음은 유저와 나눈 최근 대화입니다:
|
39 |
+
{memory_str if memory_str else "(대화 기록 없음)"}
|
|
|
|
|
40 |
|
41 |
+
지금 유저가 이렇게 말했습니다: "{user_input}"
|
42 |
+
이 말에 대해 당신은 {npc.name}으로서 자연스럽게 한국어로 답변하세요.
|
43 |
"""
|
44 |
+
|
45 |
+
try:
|
46 |
+
response = llm.generate_content(prompt)
|
47 |
+
npc_reply = response.text.strip()
|
48 |
+
except Exception as e:
|
49 |
+
npc_reply = f"[에러 발생: {str(e)}]"
|
50 |
|
51 |
# NPC 기억에 대화 추가 및 관계 점수 업데이트
|
52 |
npc.remember_conversation(user_input, npc_reply)
|
|
|
62 |
|
63 |
return jsonify({'response': npc_reply})
|
64 |
|
65 |
+
# npc 상태 정보 API
|
66 |
@npc_bp.route('/npc_info', methods=['GET'])
|
67 |
def npc_info():
|
68 |
npc_name = request.args.get('npc')
|
requirements.txt
CHANGED
@@ -1,66 +1,66 @@
|
|
1 |
accelerate==1.7.0
|
2 |
-
asttokens
|
3 |
bitsandbytes==0.45.5
|
4 |
blinker==1.9.0
|
5 |
certifi==2025.4.26
|
6 |
charset-normalizer==3.4.2
|
7 |
click==8.2.0
|
8 |
colorama==0.4.6
|
9 |
-
comm
|
10 |
-
debugpy
|
11 |
-
decorator
|
12 |
-
exceptiongroup
|
13 |
-
executing
|
14 |
filelock==3.18.0
|
15 |
Flask==3.1.1
|
16 |
fsspec==2025.5.0
|
17 |
huggingface-hub==0.32.0
|
18 |
idna==3.10
|
19 |
-
|
20 |
-
ipykernel
|
21 |
-
ipython
|
22 |
-
|
23 |
itsdangerous==2.2.0
|
24 |
-
jedi
|
25 |
Jinja2==3.1.6
|
26 |
-
|
27 |
-
|
28 |
MarkupSafe==3.0.2
|
29 |
-
matplotlib-inline
|
30 |
mpmath==1.3.0
|
31 |
-
|
32 |
networkx==3.4.2
|
33 |
numpy==2.2.6
|
34 |
-
packaging
|
35 |
-
parso
|
36 |
-
pickleshare
|
37 |
pillow==11.0.0
|
38 |
-
platformdirs
|
39 |
-
|
40 |
-
psutil
|
41 |
-
|
42 |
-
Pygments
|
43 |
-
python-dateutil
|
44 |
python-dotenv==1.1.0
|
45 |
pywin32==304
|
46 |
PyYAML==6.0.2
|
47 |
-
pyzmq
|
48 |
regex==2024.11.6
|
49 |
requests==2.32.3
|
50 |
safetensors==0.5.3
|
51 |
-
six
|
52 |
-
|
53 |
sympy==1.14.0
|
54 |
tokenizers==0.21.1
|
55 |
torch==2.7.0+cu118
|
56 |
torchaudio==2.7.0+cu118
|
57 |
torchvision==0.22.0+cu118
|
58 |
-
tornado
|
59 |
tqdm==4.67.1
|
60 |
-
traitlets
|
61 |
transformers==4.52.3
|
62 |
-
|
63 |
urllib3==2.4.0
|
64 |
-
wcwidth
|
65 |
Werkzeug==3.1.3
|
66 |
-
zipp
|
|
|
1 |
accelerate==1.7.0
|
2 |
+
asttokens
|
3 |
bitsandbytes==0.45.5
|
4 |
blinker==1.9.0
|
5 |
certifi==2025.4.26
|
6 |
charset-normalizer==3.4.2
|
7 |
click==8.2.0
|
8 |
colorama==0.4.6
|
9 |
+
comm
|
10 |
+
debugpy
|
11 |
+
decorator
|
12 |
+
exceptiongroup
|
13 |
+
executing
|
14 |
filelock==3.18.0
|
15 |
Flask==3.1.1
|
16 |
fsspec==2025.5.0
|
17 |
huggingface-hub==0.32.0
|
18 |
idna==3.10
|
19 |
+
importlib-metadata
|
20 |
+
ipykernel
|
21 |
+
ipython
|
22 |
+
ipython-pygments-lexers
|
23 |
itsdangerous==2.2.0
|
24 |
+
jedi
|
25 |
Jinja2==3.1.6
|
26 |
+
jupyter-client
|
27 |
+
jupyter-core
|
28 |
MarkupSafe==3.0.2
|
29 |
+
matplotlib-inline
|
30 |
mpmath==1.3.0
|
31 |
+
nest-asyncio
|
32 |
networkx==3.4.2
|
33 |
numpy==2.2.6
|
34 |
+
packaging
|
35 |
+
parso
|
36 |
+
pickleshare
|
37 |
pillow==11.0.0
|
38 |
+
platformdirs
|
39 |
+
prompt-toolkit
|
40 |
+
psutil
|
41 |
+
pure-eval
|
42 |
+
Pygments
|
43 |
+
python-dateutil
|
44 |
python-dotenv==1.1.0
|
45 |
pywin32==304
|
46 |
PyYAML==6.0.2
|
47 |
+
pyzmq
|
48 |
regex==2024.11.6
|
49 |
requests==2.32.3
|
50 |
safetensors==0.5.3
|
51 |
+
six
|
52 |
+
stack-data
|
53 |
sympy==1.14.0
|
54 |
tokenizers==0.21.1
|
55 |
torch==2.7.0+cu118
|
56 |
torchaudio==2.7.0+cu118
|
57 |
torchvision==0.22.0+cu118
|
58 |
+
tornado
|
59 |
tqdm==4.67.1
|
60 |
+
traitlets
|
61 |
transformers==4.52.3
|
62 |
+
typing-extensions
|
63 |
urllib3==2.4.0
|
64 |
+
wcwidth
|
65 |
Werkzeug==3.1.3
|
66 |
+
zipp
|
test.ipynb
CHANGED
The diff for this file is too large to render.
See raw diff
|
|