yuto0o commited on
Commit
9332d9b
·
1 Parent(s): 977ac97

ninja移行

Browse files
config/settings.py CHANGED
@@ -39,7 +39,6 @@ INSTALLED_APPS = [
39
  "django.contrib.sessions",
40
  "django.contrib.messages",
41
  "django.contrib.staticfiles",
42
- "rest_framework",
43
  "ml_api",
44
  ]
45
 
@@ -106,9 +105,9 @@ AUTH_PASSWORD_VALIDATORS = [
106
  # Internationalization
107
  # https://docs.djangoproject.com/en/6.0/topics/i18n/
108
 
109
- LANGUAGE_CODE = "en-us"
110
 
111
- TIME_ZONE = "UTC"
112
 
113
  USE_I18N = True
114
 
 
39
  "django.contrib.sessions",
40
  "django.contrib.messages",
41
  "django.contrib.staticfiles",
 
42
  "ml_api",
43
  ]
44
 
 
105
  # Internationalization
106
  # https://docs.djangoproject.com/en/6.0/topics/i18n/
107
 
108
+ LANGUAGE_CODE = "ja"
109
 
110
+ TIME_ZONE = "Asia/Tokyo"
111
 
112
  USE_I18N = True
113
 
config/urls.py CHANGED
@@ -16,6 +16,11 @@ Including another URLconf
16
  """
17
 
18
  from django.contrib import admin
19
- from django.urls import include, path
20
 
21
- urlpatterns = [path("admin/", admin.site.urls), path("api/", include("ml_api.urls"))]
 
 
 
 
 
 
16
  """
17
 
18
  from django.contrib import admin
19
+ from django.urls import path
20
 
21
+ from ml_api.api import api
22
+
23
+ urlpatterns = [
24
+ path("admin/", admin.site.urls),
25
+ path("api/", api.urls), # ここでマウント)
26
+ ]
ml_api/api.py ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from ninja import NinjaAPI
3
+
4
+ from .model_loader import get_model
5
+ from .schemas import ChatInput, ChatOutput
6
+
7
+ # APIインスタンスの作成
8
+ api = NinjaAPI()
9
+
10
+
11
+ @api.post("/chat", response=ChatOutput)
12
+ def chat(request, data: ChatInput):
13
+ """
14
+ Qwenモデルを使用したチャットAPI
15
+ """
16
+ user_input = data.text # Schema経由で安全にアクセス
17
+
18
+ # モデルのロード(初回のみロードが走る)
19
+ model, tokenizer = get_model()
20
+
21
+ # 1. 会話フォーマットの作成
22
+ messages = [
23
+ {
24
+ "role": "system",
25
+ "content": "あなたは親切でフレンドリーなAIアシスタント「qwen」です。自然な日本語で簡潔に返事をしてください。",
26
+ },
27
+ {"role": "user", "content": user_input},
28
+ ]
29
+
30
+ # 2. プロンプトへの変換
31
+ text = tokenizer.apply_chat_template(
32
+ messages, tokenize=False, add_generation_prompt=True
33
+ )
34
+
35
+ inputs = tokenizer([text], return_tensors="pt").to(model.device)
36
+
37
+ # 3. 生成
38
+ with torch.no_grad():
39
+ generated_ids = model.generate(
40
+ **inputs,
41
+ max_new_tokens=256,
42
+ do_sample=True,
43
+ temperature=0.7,
44
+ top_p=0.9,
45
+ )
46
+
47
+ # 4. デコード
48
+ generated_ids = [
49
+ output_ids[len(input_ids) :]
50
+ for input_ids, output_ids in zip(inputs.input_ids, generated_ids)
51
+ ]
52
+ response_text = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
53
+
54
+ # ChatOutputスキーマに合わせてdictを返す
55
+ return {"result": response_text}
ml_api/schemas.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ from ninja import Schema
2
+
3
+
4
+ class ChatInput(Schema):
5
+ text: str
6
+
7
+
8
+ class ChatOutput(Schema):
9
+ result: str
ml_api/tests.py CHANGED
@@ -1,3 +1 @@
1
- from django.test import TestCase
2
-
3
  # Create your tests here.
 
 
 
1
  # Create your tests here.
ml_api/urls.py DELETED
@@ -1,9 +0,0 @@
1
- from django.urls import path
2
-
3
- from .views import ChatView
4
-
5
- urlpatterns = [
6
- # エンドポイント名を 'chat' とします
7
- # アクセスURLの末尾になります
8
- path("chat/", ChatView.as_view(), name="chat"),
9
- ]
 
 
 
 
 
 
 
 
 
 
ml_api/views.py DELETED
@@ -1,86 +0,0 @@
1
- import torch
2
- from rest_framework.response import Response
3
- from rest_framework.views import APIView
4
-
5
- from ml_api.model_loader import get_model
6
-
7
-
8
- class ChatView(APIView):
9
- def post(self, request):
10
- user_input = request.data.get("text", "")
11
-
12
- # ここで呼び出す(初回のみロードが走る)
13
- model, tokenizer = get_model()
14
-
15
- # 1. 会話フォーマットの作成
16
- messages = [
17
- {
18
- "role": "system",
19
- "content": "あなたは親切でフレンドリーなAIアシスタント「qwen」です。。自然な日本語で簡潔に返事をしてください。",
20
- },
21
- {"role": "user", "content": user_input},
22
- ]
23
- print(user_input)
24
-
25
- # 2. プロンプトへの変換
26
- text = tokenizer.apply_chat_template(
27
- messages, tokenize=False, add_generation_prompt=True
28
- )
29
-
30
- inputs = tokenizer([text], return_tensors="pt").to(model.device)
31
-
32
- # 3. 生成
33
- with torch.no_grad():
34
- generated_ids = model.generate(
35
- **inputs,
36
- max_new_tokens=256,
37
- do_sample=True,
38
- temperature=0.7,
39
- top_p=0.9,
40
- )
41
-
42
- # 4. デコード
43
- generated_ids = [
44
- output_ids[len(input_ids) :]
45
- for input_ids, output_ids in zip(inputs.input_ids, generated_ids)
46
- ]
47
- response_text = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[
48
- 0
49
- ]
50
-
51
- return Response({"result": response_text})
52
-
53
-
54
- # class ChatView(APIView):
55
- # def post(self, request):
56
- # input_text = request.data.get("text", "")
57
-
58
- # # 簡易的なプロンプトエンジニアリング
59
- # # モデルに「会話」であることを認識させるフォーマット
60
- # prompt = f"ユーザー: {input_text}\nシステム: "
61
-
62
- # app_config = apps.get_app_config("ml_api")
63
- # tokenizer = app_config.tokenizer
64
- # model = app_config.model
65
-
66
- # # トークン化
67
- # inputs = tokenizer(prompt, return_tensors="pt", add_special_tokens=False)
68
-
69
- # # 生成
70
- # with torch.no_grad():
71
- # output_ids = model.generate(
72
- # inputs["input_ids"],
73
- # max_new_tokens=50, # 返信の長さ
74
- # do_sample=True,
75
- # temperature=0.7, # 創造性(高いほどランダム)
76
- # pad_token_id=tokenizer.pad_token_id,
77
- # eos_token_id=tokenizer.eos_token_id,
78
- # )
79
-
80
- # # デコード
81
- # output = tokenizer.decode(output_ids.tolist()[0])
82
-
83
- # # プロンプト部分を除去して返信部分だけ抽出
84
- # response_text = output.split("システム: ")[-1].strip()
85
-
86
- # return Response({"result": response_text})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
pyproject.toml CHANGED
@@ -7,7 +7,6 @@ requires-python = ">=3.12"
7
  dependencies = [
8
  "accelerate>=1.12.0",
9
  "django>=6.0",
10
- "djangorestframework>=3.16.1",
11
  "protobuf>=6.33.2",
12
  "sentencepiece>=0.2.1",
13
  "torch>=2.9.1",
 
7
  dependencies = [
8
  "accelerate>=1.12.0",
9
  "django>=6.0",
 
10
  "protobuf>=6.33.2",
11
  "sentencepiece>=0.2.1",
12
  "torch>=2.9.1",
requirements.txt CHANGED
@@ -9,10 +9,6 @@ certifi==2025.11.12
9
  charset-normalizer==3.4.4
10
  # via requests
11
  django==6.0
12
- # via
13
- # django-ai-chat (pyproject.toml)
14
- # djangorestframework
15
- djangorestframework==3.16.1
16
  # via django-ai-chat (pyproject.toml)
17
  filelock==3.20.0
18
  # via
 
9
  charset-normalizer==3.4.4
10
  # via requests
11
  django==6.0
 
 
 
 
12
  # via django-ai-chat (pyproject.toml)
13
  filelock==3.20.0
14
  # via
uv.lock CHANGED
@@ -125,7 +125,6 @@ source = { virtual = "." }
125
  dependencies = [
126
  { name = "accelerate" },
127
  { name = "django" },
128
- { name = "djangorestframework" },
129
  { name = "protobuf" },
130
  { name = "sentencepiece" },
131
  { name = "torch" },
@@ -136,25 +135,12 @@ dependencies = [
136
  requires-dist = [
137
  { name = "accelerate", specifier = ">=1.12.0" },
138
  { name = "django", specifier = ">=6.0" },
139
- { name = "djangorestframework", specifier = ">=3.16.1" },
140
  { name = "protobuf", specifier = ">=6.33.2" },
141
  { name = "sentencepiece", specifier = ">=0.2.1" },
142
  { name = "torch", specifier = ">=2.9.1" },
143
  { name = "transformers", specifier = ">=4.57.3" },
144
  ]
145
 
146
- [[package]]
147
- name = "djangorestframework"
148
- version = "3.16.1"
149
- source = { registry = "https://pypi.org/simple" }
150
- dependencies = [
151
- { name = "django" },
152
- ]
153
- sdist = { url = "https://files.pythonhosted.org/packages/8a/95/5376fe618646fde6899b3cdc85fd959716bb67542e273a76a80d9f326f27/djangorestframework-3.16.1.tar.gz", hash = "sha256:166809528b1aced0a17dc66c24492af18049f2c9420dbd0be29422029cfc3ff7", size = 1089735, upload-time = "2025-08-06T17:50:53.251Z" }
154
- wheels = [
155
- { url = "https://files.pythonhosted.org/packages/b0/ce/bf8b9d3f415be4ac5588545b5fcdbbb841977db1c1d923f7568eeabe1689/djangorestframework-3.16.1-py3-none-any.whl", hash = "sha256:33a59f47fb9c85ede792cbf88bde71893bcda0667bc573f784649521f1102cec", size = 1080442, upload-time = "2025-08-06T17:50:50.667Z" },
156
- ]
157
-
158
  [[package]]
159
  name = "filelock"
160
  version = "3.20.0"
 
125
  dependencies = [
126
  { name = "accelerate" },
127
  { name = "django" },
 
128
  { name = "protobuf" },
129
  { name = "sentencepiece" },
130
  { name = "torch" },
 
135
  requires-dist = [
136
  { name = "accelerate", specifier = ">=1.12.0" },
137
  { name = "django", specifier = ">=6.0" },
 
138
  { name = "protobuf", specifier = ">=6.33.2" },
139
  { name = "sentencepiece", specifier = ">=0.2.1" },
140
  { name = "torch", specifier = ">=2.9.1" },
141
  { name = "transformers", specifier = ">=4.57.3" },
142
  ]
143
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  [[package]]
145
  name = "filelock"
146
  version = "3.20.0"