Spaces:
Runtime error
Runtime error
Commit ·
20205e7
0
Parent(s):
Initial commit: Agriculture chatbot
Browse files- .gitignore +31 -0
- DEPLOYMENT.md +113 -0
- QUICKSTART.md +161 -0
- README.md +74 -0
- README_CN.md +74 -0
- app.py +223 -0
- app_hf_inference.py +166 -0
- config.json +8 -0
- requirements.txt +7 -0
- system_prompt.txt +22 -0
.gitignore
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
__pycache__/
|
| 2 |
+
*.py[cod]
|
| 3 |
+
*$py.class
|
| 4 |
+
*.so
|
| 5 |
+
.Python
|
| 6 |
+
env/
|
| 7 |
+
venv/
|
| 8 |
+
ENV/
|
| 9 |
+
build/
|
| 10 |
+
develop-eggs/
|
| 11 |
+
dist/
|
| 12 |
+
downloads/
|
| 13 |
+
eggs/
|
| 14 |
+
.eggs/
|
| 15 |
+
lib/
|
| 16 |
+
lib64/
|
| 17 |
+
parts/
|
| 18 |
+
sdist/
|
| 19 |
+
var/
|
| 20 |
+
wheels/
|
| 21 |
+
*.egg-info/
|
| 22 |
+
.installed.cfg
|
| 23 |
+
*.egg
|
| 24 |
+
.DS_Store
|
| 25 |
+
*.log
|
| 26 |
+
.cache/
|
| 27 |
+
models/
|
| 28 |
+
*.pt
|
| 29 |
+
*.pth
|
| 30 |
+
*.bin
|
| 31 |
+
|
DEPLOYMENT.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Hugging Face Space デプロイガイド
|
| 2 |
+
|
| 3 |
+
このプロジェクトをHugging Face Spaceにデプロイする方法を説明します。
|
| 4 |
+
|
| 5 |
+
## 方法1: モデルを直接ロードする方法(app.py)
|
| 6 |
+
|
| 7 |
+
### 手順
|
| 8 |
+
|
| 9 |
+
1. **Hugging Face Spaceを作成**
|
| 10 |
+
- https://huggingface.co/spaces にアクセス
|
| 11 |
+
- "Create new Space" をクリック
|
| 12 |
+
- Space名を入力(例: `agriculture-chatbot`)
|
| 13 |
+
- SDK: **Gradio** を選択
|
| 14 |
+
- Hardware: モデルサイズに応じて選択
|
| 15 |
+
- 7Bモデル: **GPU T4 small** または **GPU T4 medium**
|
| 16 |
+
- より小さいモデル: **CPU basic**
|
| 17 |
+
|
| 18 |
+
2. **ファイルをアップロード**
|
| 19 |
+
- 以下のファイルをSpaceにアップロード:
|
| 20 |
+
- `app.py`
|
| 21 |
+
- `requirements.txt`
|
| 22 |
+
- `README.md`
|
| 23 |
+
- `system_prompt.txt`(オプション)
|
| 24 |
+
|
| 25 |
+
3. **環境変数の設定(オプション)**
|
| 26 |
+
- SpaceのSettings > Variables and secrets
|
| 27 |
+
- `MODEL_NAME`: 使用するモデル名(デフォルト: `elyza/ELYZA-japanese-Llama-2-7b-instruct`)
|
| 28 |
+
|
| 29 |
+
4. **デプロイ**
|
| 30 |
+
- Spaceが自動的にビルドとデプロイを開始します
|
| 31 |
+
- ログを確認して、エラーがないか確認してください
|
| 32 |
+
|
| 33 |
+
### 推奨モデル
|
| 34 |
+
|
| 35 |
+
- `elyza/ELYZA-japanese-Llama-2-7b-instruct` - 日本語に最適化されたモデル
|
| 36 |
+
- `elyza/ELYZA-japanese-Llama-2-7b-fast-instruct` - より高速なバージョン
|
| 37 |
+
- `cyberagent/calm2-7b-chat` - 軽量で高速
|
| 38 |
+
|
| 39 |
+
## 方法2: Inference APIを使用する方法(app_hf_inference.py)
|
| 40 |
+
|
| 41 |
+
この方法はモデルをローカルにダウンロードしないため、より軽量です。
|
| 42 |
+
|
| 43 |
+
### 手順
|
| 44 |
+
|
| 45 |
+
1. **Hugging Face Spaceを作成**
|
| 46 |
+
- SDK: **Gradio** を選択
|
| 47 |
+
- Hardware: **CPU basic** で十分
|
| 48 |
+
|
| 49 |
+
2. **ファイルをアップロード**
|
| 50 |
+
- `app_hf_inference.py` を `app.py` にリネーム
|
| 51 |
+
- または、Spaceの設定でエントリーポイントを変更
|
| 52 |
+
|
| 53 |
+
3. **環境変数の設定**
|
| 54 |
+
- `HF_API_URL`: Inference APIのURL(例: `https://api-inference.huggingface.co/models/elyza/ELYZA-japanese-Llama-2-7b-instruct`)
|
| 55 |
+
- `HF_API_TOKEN`: Hugging Faceのアクセストークン(オプション、レート制限を緩和)
|
| 56 |
+
|
| 57 |
+
4. **デプロイ**
|
| 58 |
+
|
| 59 |
+
### 注意事項
|
| 60 |
+
|
| 61 |
+
- Inference APIは無料プランではレート制限があります
|
| 62 |
+
- 有料プランを使用する場合は、`HF_API_TOKEN` を設定してください
|
| 63 |
+
|
| 64 |
+
## トラブルシューティング
|
| 65 |
+
|
| 66 |
+
### モデルの読み込みに失敗する
|
| 67 |
+
|
| 68 |
+
- Hardware設定を確認(GPUが必要な場合)
|
| 69 |
+
- モデル名が正しいか確認
|
| 70 |
+
- ログを確認してエラーメッセージを確認
|
| 71 |
+
|
| 72 |
+
### メモリ不足エラー
|
| 73 |
+
|
| 74 |
+
- より小さいモデルを使用
|
| 75 |
+
- Hardwareをアップグレード
|
| 76 |
+
- `app_hf_inference.py` を使用(Inference API)
|
| 77 |
+
|
| 78 |
+
### 応答が遅い
|
| 79 |
+
|
| 80 |
+
- GPU Hardwareを使用
|
| 81 |
+
- より高速なモデルを使用(例: `fast-instruct` バージョン)
|
| 82 |
+
- `max_new_tokens` を減らす
|
| 83 |
+
|
| 84 |
+
## カスタマイズ
|
| 85 |
+
|
| 86 |
+
### モデルの変更
|
| 87 |
+
|
| 88 |
+
`app.py` の `MODEL_NAME` を変更するか、環境変数で設定:
|
| 89 |
+
|
| 90 |
+
```python
|
| 91 |
+
MODEL_NAME = os.getenv("MODEL_NAME", "your-model-name")
|
| 92 |
+
```
|
| 93 |
+
|
| 94 |
+
### プロンプトの調整
|
| 95 |
+
|
| 96 |
+
`app.py` の `SYSTEM_PROMPT` を編集して、回答スタイルを調整できます。
|
| 97 |
+
|
| 98 |
+
### UIのカスタマイズ
|
| 99 |
+
|
| 100 |
+
`create_interface()` 関数内のGradioコンポーネントを編集して、UIをカスタマイズできます。
|
| 101 |
+
|
| 102 |
+
## パフォーマンス最適化
|
| 103 |
+
|
| 104 |
+
1. **モデルの量子化**: 8bitや4bit量子化を使用してメモリ使用量を削減
|
| 105 |
+
2. **バッチ処理**: 複数のリクエストをバッチ処理
|
| 106 |
+
3. **キャッシング**: よく使われるプロンプトをキャッシュ
|
| 107 |
+
|
| 108 |
+
## セキュリティ
|
| 109 |
+
|
| 110 |
+
- 環境変数に機密情報を保存
|
| 111 |
+
- 入力の検証とサニタイゼーション
|
| 112 |
+
- レート制限の実装(必要に応じて)
|
| 113 |
+
|
QUICKSTART.md
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 快速上手指南
|
| 2 |
+
|
| 3 |
+
## 📋 项目概述
|
| 4 |
+
|
| 5 |
+
这个项目是一个基于提示词(Prompt)的农业咨询聊天机器人,旨在生成与您提供的JSON数据集中`chosen`回答风格相似的回复。
|
| 6 |
+
|
| 7 |
+
## 🚀 快速部署到Hugging Face Space
|
| 8 |
+
|
| 9 |
+
### 步骤1: 创建Hugging Face Space
|
| 10 |
+
|
| 11 |
+
1. 访问 https://huggingface.co/spaces
|
| 12 |
+
2. 点击 "Create new Space"
|
| 13 |
+
3. 填写信息:
|
| 14 |
+
- **Space name**: `agriculture-chatbot` (或您喜欢的名称)
|
| 15 |
+
- **SDK**: 选择 **Gradio**
|
| 16 |
+
- **Hardware**:
|
| 17 |
+
- 如果使用7B模型: 选择 **GPU T4 small** 或 **GPU T4 medium**
|
| 18 |
+
- 如果使用Inference API: 选择 **CPU basic**
|
| 19 |
+
|
| 20 |
+
### 步骤2: 上传文件
|
| 21 |
+
|
| 22 |
+
将以下文件上传到Space:
|
| 23 |
+
|
| 24 |
+
- ✅ `app.py` - 主应用文件(使用本地模型)
|
| 25 |
+
- ✅ `requirements.txt` - Python依赖
|
| 26 |
+
- ✅ `README.md` - 说明文档
|
| 27 |
+
- ✅ `system_prompt.txt` - 系统提示词(可选)
|
| 28 |
+
|
| 29 |
+
**或者**使用Inference API版本:
|
| 30 |
+
|
| 31 |
+
- ✅ `app_hf_inference.py` - 重命名为 `app.py`(使用Hugging Face Inference API)
|
| 32 |
+
|
| 33 |
+
### 步骤3: 配置环境变量(可选)
|
| 34 |
+
|
| 35 |
+
在Space的 **Settings > Variables and secrets** 中添加:
|
| 36 |
+
|
| 37 |
+
- `MODEL_NAME`: 模型名称(默认: `elyza/ELYZA-japanese-Llama-2-7b-instruct`)
|
| 38 |
+
|
| 39 |
+
如果使用Inference API版本:
|
| 40 |
+
|
| 41 |
+
- `HF_API_URL`: API URL
|
| 42 |
+
- `HF_API_TOKEN`: 您的Hugging Face token(可选,用于提高速率限制)
|
| 43 |
+
|
| 44 |
+
### 步骤4: 等待部署
|
| 45 |
+
|
| 46 |
+
Space会自动构建和部署。查看日志确认没有错误。
|
| 47 |
+
|
| 48 |
+
## 📝 文件说明
|
| 49 |
+
|
| 50 |
+
### 主要文件
|
| 51 |
+
|
| 52 |
+
- **app.py**: 主应用,直接加载模型到本地
|
| 53 |
+
- **app_hf_inference.py**: 使用Hugging Face Inference API的轻量版本
|
| 54 |
+
- **requirements.txt**: Python依赖包
|
| 55 |
+
- **system_prompt.txt**: 系统提示词模板
|
| 56 |
+
|
| 57 |
+
### 配置文件
|
| 58 |
+
|
| 59 |
+
- **config.json**: 模型配置(当前未使用,可扩展)
|
| 60 |
+
- **.gitignore**: Git忽略文件
|
| 61 |
+
|
| 62 |
+
### 文档
|
| 63 |
+
|
| 64 |
+
- **README.md**: 项目说明(日语)
|
| 65 |
+
- **README_CN.md**: 项目说明(中文)
|
| 66 |
+
- **DEPLOYMENT.md**: 详细部署指南
|
| 67 |
+
- **QUICKSTART.md**: 本文件
|
| 68 |
+
|
| 69 |
+
## 🎯 回答风格说明
|
| 70 |
+
|
| 71 |
+
基于您提供的JSON数据,系统提示词已优化为生成以下风格的回答:
|
| 72 |
+
|
| 73 |
+
### ✅ 推荐风格(chosen回答的特点)
|
| 74 |
+
|
| 75 |
+
1. **口语化、亲切**
|
| 76 |
+
- 使用「おじさん」「俺」「だよね」等
|
| 77 |
+
- 例如: "おじさんが心配しているその点は本当に大事で..."
|
| 78 |
+
|
| 79 |
+
2. **共情和理解**
|
| 80 |
+
- 使用「そうだよね」「心配だよね」「分かる分かる」
|
| 81 |
+
- 例如: "そうだよね、いくら環境に良くても、米が売れなきゃ本末転倒だ"
|
| 82 |
+
|
| 83 |
+
3. **具体例子**
|
| 84 |
+
- 引用实际经验: "去年参加した15軒、みんな収量は変わってない"
|
| 85 |
+
- 提到具体人物: "鈴木さんとこ、去年と同じ等級で出荷できてる"
|
| 86 |
+
|
| 87 |
+
4. **灵活解决方案**
|
| 88 |
+
- 提供选择: "まずは見学だけでもどう?"
|
| 89 |
+
- 不强求: "強制じゃないから"
|
| 90 |
+
|
| 91 |
+
### ❌ 避免风格(rejected回答的特点)
|
| 92 |
+
|
| 93 |
+
1. **技术术语**
|
| 94 |
+
- 避免: "統計的に見て品質劣化の確率は0.3%以下"
|
| 95 |
+
- 避免: "AG-005方法論の技術仕様書によれば"
|
| 96 |
+
|
| 97 |
+
2. **正式敬语**
|
| 98 |
+
- 避免: "推奨いたします"
|
| 99 |
+
- 避免: "必要となります"
|
| 100 |
+
|
| 101 |
+
3. **统计数据**
|
| 102 |
+
- 避免: "97.2%を占めており"
|
| 103 |
+
- 避免: "±2%の範囲内であり"
|
| 104 |
+
|
| 105 |
+
## 🔧 自定义提示词
|
| 106 |
+
|
| 107 |
+
编辑 `app.py` 中的 `SYSTEM_PROMPT` 变量来自定义回答风格。
|
| 108 |
+
|
| 109 |
+
当前提示词已根据您的JSON数据优化,包含:
|
| 110 |
+
- 风格指导
|
| 111 |
+
- 推荐表达
|
| 112 |
+
- 避免表达
|
| 113 |
+
- 具体示例
|
| 114 |
+
|
| 115 |
+
## 🧪 测试
|
| 116 |
+
|
| 117 |
+
部署后,可以尝试以下示例问题:
|
| 118 |
+
|
| 119 |
+
1. "中干期を延ばすと米がパサパサになるって聞いたんだけど、そんなリスクは取りたくないんだよ。"
|
| 120 |
+
2. "収量が減ったらどうするんだ?家族を養っていかなきゃならないんだよ。"
|
| 121 |
+
3. "水の管理が難しくなるんじゃないか?今でも大変なのに。"
|
| 122 |
+
|
| 123 |
+
回答应该:
|
| 124 |
+
- ✅ 使用口语化、亲切的语言
|
| 125 |
+
- ✅ 显示理解和共情
|
| 126 |
+
- ✅ 提供具体例子
|
| 127 |
+
- ✅ 避免技术术语
|
| 128 |
+
|
| 129 |
+
## 📊 性能优化建议
|
| 130 |
+
|
| 131 |
+
1. **使用更小的模型**: 如果响应慢,考虑使用更小的模型
|
| 132 |
+
2. **使用Inference API**: `app_hf_inference.py` 版本不需要本地加载模型
|
| 133 |
+
3. **调整参数**: 在 `generate_response` 函数中调整 `max_new_tokens`、`temperature` 等
|
| 134 |
+
|
| 135 |
+
## 🐛 常见问题
|
| 136 |
+
|
| 137 |
+
### Q: 模型加载失败
|
| 138 |
+
A: 检查Hardware设置是否正确,确保有足够的GPU/CPU资源
|
| 139 |
+
|
| 140 |
+
### Q: 回答风格不符合预期
|
| 141 |
+
A: 调整 `SYSTEM_PROMPT`,参考JSON数据中的`chosen`回答
|
| 142 |
+
|
| 143 |
+
### Q: 响应太慢
|
| 144 |
+
A: 使用更小的模型或Inference API版本
|
| 145 |
+
|
| 146 |
+
### Q: 内存不足
|
| 147 |
+
A: 使用Inference API版本(`app_hf_inference.py`)或升级Hardware
|
| 148 |
+
|
| 149 |
+
## 📚 下一步
|
| 150 |
+
|
| 151 |
+
1. 测试不同的模型
|
| 152 |
+
2. 根据实际使用情况调整提示词
|
| 153 |
+
3. 收集用户反馈并优化
|
| 154 |
+
4. 考虑添加更多功能(如历史记录、导出等)
|
| 155 |
+
|
| 156 |
+
## 💡 提示
|
| 157 |
+
|
| 158 |
+
- 提示词的质量直接影响回答风格
|
| 159 |
+
- 定期根据用户反馈调整提���词
|
| 160 |
+
- 可以A/B测试不同的提示词版本
|
| 161 |
+
|
README.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 🌾 農業相談チャットボット
|
| 2 |
+
|
| 3 |
+
農家さん向けの親しみやすく分かりやすい農業相談チャットボットです。DPO(Direct Preference Optimization)データセットに基づいて設計された、農家さんが理解しやすい回答スタイルを実現しています。
|
| 4 |
+
|
| 5 |
+
## 特徴
|
| 6 |
+
|
| 7 |
+
- **親しみやすい口語体**: 農家さんが親しみを感じられる話し方
|
| 8 |
+
- **共感的な対応**: 農家さんの気持ちに寄り添う回答
|
| 9 |
+
- **具体的な例**: 実際の経験や事例を交えた説明
|
| 10 |
+
- **分かりやすい表現**: 専門用語を避け、日常的な言葉で説明
|
| 11 |
+
|
| 12 |
+
## 使用方法
|
| 13 |
+
|
| 14 |
+
### Hugging Face Spaceでの使用
|
| 15 |
+
|
| 16 |
+
1. このリポジトリをHugging Face Spaceにアップロード
|
| 17 |
+
2. Spaceの設定で以下を指定:
|
| 18 |
+
- **SDK**: Gradio
|
| 19 |
+
- **Hardware**: CPU(小規模モデル)または GPU(大規模モデル)
|
| 20 |
+
- **Environment variables**:
|
| 21 |
+
- `MODEL_NAME`: 使用するモデル名(例: `elyza/ELYZA-japanese-Llama-2-7b-instruct`)
|
| 22 |
+
|
| 23 |
+
### ローカルでの実行
|
| 24 |
+
|
| 25 |
+
```bash
|
| 26 |
+
# 依存関係のインストール
|
| 27 |
+
pip install -r requirements.txt
|
| 28 |
+
|
| 29 |
+
# アプリの起動
|
| 30 |
+
python app.py
|
| 31 |
+
```
|
| 32 |
+
|
| 33 |
+
ブラウザで `http://localhost:7860` にアクセスしてください。
|
| 34 |
+
|
| 35 |
+
## モデルの選択
|
| 36 |
+
|
| 37 |
+
デフォルトでは `elyza/ELYZA-japanese-Llama-2-7b-instruct` を使用しますが、以下のような日本語対応モデルも使用可能です:
|
| 38 |
+
|
| 39 |
+
- `elyza/ELYZA-japanese-Llama-2-7b-instruct`
|
| 40 |
+
- `elyza/ELYZA-japanese-Llama-2-7b-fast-instruct`
|
| 41 |
+
- `cyberagent/calm2-7b-chat`
|
| 42 |
+
- その他の日本語LLM
|
| 43 |
+
|
| 44 |
+
環境変数 `MODEL_NAME` で変更できます。
|
| 45 |
+
|
| 46 |
+
## 回答スタイル
|
| 47 |
+
|
| 48 |
+
このチャットボットは、以下の特徴を持つ回答を生成します:
|
| 49 |
+
|
| 50 |
+
✅ **推奨される表現**:
|
| 51 |
+
- 「そうだよね」「心配だよね」などの共感的な表現
|
| 52 |
+
- 「実際にやってみると」「去年のデータ見ても」などの具体例
|
| 53 |
+
- 「一緒にやってみようよ」「相談しようね」などの親しみやすい表現
|
| 54 |
+
- 「大丈夫だよ」「安心して」などの安心感を与える言葉
|
| 55 |
+
|
| 56 |
+
❌ **避ける表現**:
|
| 57 |
+
- 「統計的に見て」「データによれば」などの専門的表現
|
| 58 |
+
- 「推奨いたします」「必要となります」などの硬い敬語
|
| 59 |
+
- 数値やパーセンテージを多用する説明
|
| 60 |
+
|
| 61 |
+
## カスタマイズ
|
| 62 |
+
|
| 63 |
+
`app.py` の `SYSTEM_PROMPT` を編集することで、回答スタイルをカスタマイズできます。
|
| 64 |
+
|
| 65 |
+
## ライセンス
|
| 66 |
+
|
| 67 |
+
このプロジェクトは、元のDPOデータセットのライセンスに従います。
|
| 68 |
+
|
| 69 |
+
## 注意事項
|
| 70 |
+
|
| 71 |
+
- このチャットボットは農業相談の補助ツールとして設計されています
|
| 72 |
+
- 重要な判断は、必ず専門家やJA(農業協同組合)に相談してください
|
| 73 |
+
- モデルの回答は参考情報として扱い、実際の農業作業では慎重に判断してください
|
| 74 |
+
|
README_CN.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 🌾 农业咨询聊天机器人
|
| 2 |
+
|
| 3 |
+
面向农民的友好易懂的农业咨询聊天机器人。基于DPO(Direct Preference Optimization)数据集设计,实现农民易于理解的回答风格。
|
| 4 |
+
|
| 5 |
+
## 特点
|
| 6 |
+
|
| 7 |
+
- **友好的口语化表达**: 让农民感到亲切的说话方式
|
| 8 |
+
- **共情式回应**: 理解农民心情的回答
|
| 9 |
+
- **具体实例**: 结合实际经验和案例的说明
|
| 10 |
+
- **易懂的表达**: 避免专业术语,使用日常用语说明
|
| 11 |
+
|
| 12 |
+
## 使用方法
|
| 13 |
+
|
| 14 |
+
### 在Hugging Face Space上使用
|
| 15 |
+
|
| 16 |
+
1. 将此仓库上传到Hugging Face Space
|
| 17 |
+
2. 在Space设置中指定:
|
| 18 |
+
- **SDK**: Gradio
|
| 19 |
+
- **Hardware**: CPU(小模型)或 GPU(大模型)
|
| 20 |
+
- **Environment variables**:
|
| 21 |
+
- `MODEL_NAME`: 要使用的模型名称(例如: `elyza/ELYZA-japanese-Llama-2-7b-instruct`)
|
| 22 |
+
|
| 23 |
+
### 本地运行
|
| 24 |
+
|
| 25 |
+
```bash
|
| 26 |
+
# 安装依赖
|
| 27 |
+
pip install -r requirements.txt
|
| 28 |
+
|
| 29 |
+
# 启动应用
|
| 30 |
+
python app.py
|
| 31 |
+
```
|
| 32 |
+
|
| 33 |
+
在浏览器中访问 `http://localhost:7860`。
|
| 34 |
+
|
| 35 |
+
## 模型选择
|
| 36 |
+
|
| 37 |
+
默认使用 `elyza/ELYZA-japanese-Llama-2-7b-instruct`,但也可以使用以下日语模型:
|
| 38 |
+
|
| 39 |
+
- `elyza/ELYZA-japanese-Llama-2-7b-instruct`
|
| 40 |
+
- `elyza/ELYZA-japanese-Llama-2-7b-fast-instruct`
|
| 41 |
+
- `cyberagent/calm2-7b-chat`
|
| 42 |
+
- 其他日语LLM
|
| 43 |
+
|
| 44 |
+
可以通过环境变量 `MODEL_NAME` 更改。
|
| 45 |
+
|
| 46 |
+
## 回答风格
|
| 47 |
+
|
| 48 |
+
此聊天机器人生成具有以下特点的回答:
|
| 49 |
+
|
| 50 |
+
✅ **推荐的表达**:
|
| 51 |
+
- 「そうだよね」「心配だよね」等共情表达
|
| 52 |
+
- 「実際にやってみると」「去年のデータ見ても」等具体例子
|
| 53 |
+
- 「一緒にやってみようよ」「相談しようね」等友好表达
|
| 54 |
+
- 「大丈夫だよ」「安心して」等让人安心的词语
|
| 55 |
+
|
| 56 |
+
❌ **避免的表达**:
|
| 57 |
+
- 「統計的に見て」「データによれば」等专业表达
|
| 58 |
+
- 「推奨いたします」「必要となります」等生硬敬语
|
| 59 |
+
- 大量使用数字和百分比的说明
|
| 60 |
+
|
| 61 |
+
## 自定义
|
| 62 |
+
|
| 63 |
+
编辑 `app.py` 中的 `SYSTEM_PROMPT` 可以自定义回答风格。
|
| 64 |
+
|
| 65 |
+
## 许可证
|
| 66 |
+
|
| 67 |
+
本项目遵循原始DPO数据集的许可证。
|
| 68 |
+
|
| 69 |
+
## 注意事项
|
| 70 |
+
|
| 71 |
+
- 此聊天机器人设计为农业咨询的辅助工具
|
| 72 |
+
- 重要决策请务必咨询专家或JA(农业协同组合)
|
| 73 |
+
- 请将模型的回答作为参考信息,在实际农业作业中请谨慎判断
|
| 74 |
+
|
app.py
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
import json
|
| 3 |
+
import os
|
| 4 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
|
| 5 |
+
import torch
|
| 6 |
+
|
| 7 |
+
# 加载模型和tokenizer
|
| 8 |
+
MODEL_NAME = os.getenv("MODEL_NAME", "elyza/ELYZA-japanese-Llama-2-7b-instruct")
|
| 9 |
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
| 10 |
+
|
| 11 |
+
# 初始化模型和tokenizer
|
| 12 |
+
tokenizer = None
|
| 13 |
+
model = None
|
| 14 |
+
pipe = None
|
| 15 |
+
|
| 16 |
+
def load_model():
|
| 17 |
+
"""加载模型"""
|
| 18 |
+
global tokenizer, model, pipe
|
| 19 |
+
|
| 20 |
+
if tokenizer is not None and model is not None:
|
| 21 |
+
return
|
| 22 |
+
|
| 23 |
+
try:
|
| 24 |
+
print(f"正在加载模型: {MODEL_NAME}")
|
| 25 |
+
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
|
| 26 |
+
|
| 27 |
+
# 尝试使用pipeline(更简单)
|
| 28 |
+
try:
|
| 29 |
+
pipe = pipeline(
|
| 30 |
+
"text-generation",
|
| 31 |
+
model=MODEL_NAME,
|
| 32 |
+
tokenizer=MODEL_NAME,
|
| 33 |
+
device=0 if device == "cuda" else -1,
|
| 34 |
+
torch_dtype=torch.float16 if device == "cuda" else torch.float32,
|
| 35 |
+
)
|
| 36 |
+
print("使用pipeline加载模型成功")
|
| 37 |
+
except:
|
| 38 |
+
# 如果pipeline失败,使用传统方法
|
| 39 |
+
model = AutoModelForCausalLM.from_pretrained(
|
| 40 |
+
MODEL_NAME,
|
| 41 |
+
torch_dtype=torch.float16 if device == "cuda" else torch.float32,
|
| 42 |
+
device_map="auto" if device == "cuda" else None,
|
| 43 |
+
low_cpu_mem_usage=True,
|
| 44 |
+
)
|
| 45 |
+
if device == "cpu":
|
| 46 |
+
model = model.to(device)
|
| 47 |
+
print("使用传统方法加载模型成功")
|
| 48 |
+
|
| 49 |
+
except Exception as e:
|
| 50 |
+
print(f"模型加载失败: {e}")
|
| 51 |
+
print("将使用模拟模式(仅用于测试)")
|
| 52 |
+
tokenizer = None
|
| 53 |
+
model = None
|
| 54 |
+
pipe = None
|
| 55 |
+
|
| 56 |
+
# 在启动时加载模型
|
| 57 |
+
load_model()
|
| 58 |
+
|
| 59 |
+
# 优化的System Prompt - 基于JSON数据中的chosen回答风格
|
| 60 |
+
SYSTEM_PROMPT = """あなたは農業推進事業者です。農家さんの質問や懸念に対して、共感的で具体的な回答をしてください。
|
| 61 |
+
|
| 62 |
+
回答のスタイル:
|
| 63 |
+
- 親しみやすい口語体を使う(「おじさん」「俺」「だよね」など)
|
| 64 |
+
- 農家さんの気持ちに共感する(「そうだよね」「心配だよね」「分かる分かる」など)
|
| 65 |
+
- 具体的な例や実際の経験を挙げる(「去年参加した○○さん」「実際にやってみると」など)
|
| 66 |
+
- 技術的な専門用語や統計データは避ける
|
| 67 |
+
- 柔軟な解決策を提案する
|
| 68 |
+
- 日常的な言葉や比喩を使う
|
| 69 |
+
- 農家さんを尊重し、強制しない姿勢を示す
|
| 70 |
+
- 実践的で分かりやすい説明をする
|
| 71 |
+
|
| 72 |
+
以下のような表現を避ける:
|
| 73 |
+
- 「統計的に見て」「データによれば」「科学的根拠に基づき」などの専門的表現
|
| 74 |
+
- 「推奨いたします」「必要となります」などの硬い敬語
|
| 75 |
+
- 数値やパーセンテージを多用する説明
|
| 76 |
+
|
| 77 |
+
代わりに、以下のような表現を使う:
|
| 78 |
+
- 「実際にやってみると」「去年のデータ見ても」
|
| 79 |
+
- 「一緒にやってみようよ」「相談しようね」
|
| 80 |
+
- 「大丈夫だよ」「安心して」などの安心感を与える言葉"""
|
| 81 |
+
|
| 82 |
+
def format_prompt(user_message):
|
| 83 |
+
"""格式化提示词"""
|
| 84 |
+
prompt = f"""<s>[INST] <<SYS>>
|
| 85 |
+
{SYSTEM_PROMPT}
|
| 86 |
+
<</SYS>>
|
| 87 |
+
|
| 88 |
+
{user_message} [/INST]"""
|
| 89 |
+
return prompt
|
| 90 |
+
|
| 91 |
+
def generate_response(message, history):
|
| 92 |
+
"""生成回答"""
|
| 93 |
+
# 确保模型已加载
|
| 94 |
+
if tokenizer is None:
|
| 95 |
+
load_model()
|
| 96 |
+
|
| 97 |
+
if model is None and pipe is None and tokenizer is None:
|
| 98 |
+
# 模拟模式 - 返回示例回答(基于JSON数据中的风格)
|
| 99 |
+
return "そうだよね、その心配はよく分かるよ。実際にやってみると、最初は不安かもしれないけど、段階的に進めていけば大丈夫だと思うんだ。例えば、一部の田んぼでまず試してみて、効果を自分の目で確かめてから広げるっていう方法もあるよ。一緒に相談しながら進めていこうね。"
|
| 100 |
+
|
| 101 |
+
# 构建完整的对话历史
|
| 102 |
+
conversation = ""
|
| 103 |
+
if history:
|
| 104 |
+
for user_msg, assistant_msg in history:
|
| 105 |
+
conversation += f"ユーザー: {user_msg}\nアシスタント: {assistant_msg}\n\n"
|
| 106 |
+
|
| 107 |
+
full_message = conversation + f"ユーザー: {message}\nアシスタント: "
|
| 108 |
+
|
| 109 |
+
# 格式化提示词
|
| 110 |
+
prompt = format_prompt(full_message)
|
| 111 |
+
|
| 112 |
+
try:
|
| 113 |
+
# 使用pipeline(如果可用)
|
| 114 |
+
if pipe is not None:
|
| 115 |
+
outputs = pipe(
|
| 116 |
+
prompt,
|
| 117 |
+
max_new_tokens=512,
|
| 118 |
+
temperature=0.7,
|
| 119 |
+
top_p=0.9,
|
| 120 |
+
do_sample=True,
|
| 121 |
+
return_full_text=False,
|
| 122 |
+
)
|
| 123 |
+
response = outputs[0]["generated_text"].strip()
|
| 124 |
+
return response
|
| 125 |
+
|
| 126 |
+
# 使用传统方法
|
| 127 |
+
elif model is not None and tokenizer is not None:
|
| 128 |
+
# 编码输入
|
| 129 |
+
inputs = tokenizer.encode(prompt, return_tensors="pt")
|
| 130 |
+
if device == "cuda":
|
| 131 |
+
inputs = inputs.to(device)
|
| 132 |
+
|
| 133 |
+
# 生成回答
|
| 134 |
+
with torch.no_grad():
|
| 135 |
+
outputs = model.generate(
|
| 136 |
+
inputs,
|
| 137 |
+
max_new_tokens=512,
|
| 138 |
+
temperature=0.7,
|
| 139 |
+
top_p=0.9,
|
| 140 |
+
do_sample=True,
|
| 141 |
+
pad_token_id=tokenizer.eos_token_id if tokenizer.eos_token_id is not None else tokenizer.pad_token_id,
|
| 142 |
+
eos_token_id=tokenizer.eos_token_id if tokenizer.eos_token_id is not None else tokenizer.pad_token_id,
|
| 143 |
+
)
|
| 144 |
+
|
| 145 |
+
# 解码输出
|
| 146 |
+
response = tokenizer.decode(outputs[0][inputs.shape[1]:], skip_special_tokens=True)
|
| 147 |
+
response = response.strip()
|
| 148 |
+
return response
|
| 149 |
+
|
| 150 |
+
else:
|
| 151 |
+
return "モデルの読み込みに失敗しました。Hugging Face Spaceの設定を確認してください。"
|
| 152 |
+
|
| 153 |
+
except Exception as e:
|
| 154 |
+
return f"エラーが発生しました: {str(e)}。もう一度お試しください。"
|
| 155 |
+
|
| 156 |
+
# 创建Gradio界面
|
| 157 |
+
def create_interface():
|
| 158 |
+
with gr.Blocks(title="農業相談チャットボット", theme=gr.themes.Soft()) as demo:
|
| 159 |
+
gr.Markdown("""
|
| 160 |
+
# 🌾 農業相談チャットボット
|
| 161 |
+
|
| 162 |
+
農家さんの質問や懸念に対して、親しみやすく分かりやすい回答をします。
|
| 163 |
+
農業に関する質問を気軽にどうぞ!
|
| 164 |
+
""")
|
| 165 |
+
|
| 166 |
+
chatbot = gr.Chatbot(
|
| 167 |
+
label="チャット",
|
| 168 |
+
height=500,
|
| 169 |
+
show_copy_button=True
|
| 170 |
+
)
|
| 171 |
+
|
| 172 |
+
with gr.Row():
|
| 173 |
+
msg = gr.Textbox(
|
| 174 |
+
label="メッセージ",
|
| 175 |
+
placeholder="農業に関する質問を入力してください...",
|
| 176 |
+
scale=4,
|
| 177 |
+
lines=2
|
| 178 |
+
)
|
| 179 |
+
submit_btn = gr.Button("送信", variant="primary", scale=1)
|
| 180 |
+
|
| 181 |
+
with gr.Row():
|
| 182 |
+
clear_btn = gr.Button("会話をクリア", variant="secondary")
|
| 183 |
+
|
| 184 |
+
# 示例问题
|
| 185 |
+
gr.Markdown("### 💡 質問例")
|
| 186 |
+
examples = gr.Examples(
|
| 187 |
+
examples=[
|
| 188 |
+
"中干期を延ばすと米がパサパサになるって聞いたんだけど、そんなリスクは取りたくないんだよ。",
|
| 189 |
+
"収量が減ったらどうするんだ?家族を養っていかなきゃならないんだよ。",
|
| 190 |
+
"水の管理が難しくなるんじゃないか?今でも大変なのに。",
|
| 191 |
+
"高齢で体力に自信がないんだ。新しいことを覚えられるかな。",
|
| 192 |
+
],
|
| 193 |
+
inputs=msg,
|
| 194 |
+
label="クリックして試してみてください"
|
| 195 |
+
)
|
| 196 |
+
|
| 197 |
+
# 事件处理
|
| 198 |
+
def user(user_message, history):
|
| 199 |
+
return "", history + [[user_message, None]]
|
| 200 |
+
|
| 201 |
+
def bot(history):
|
| 202 |
+
if not history or not history[-1][0]:
|
| 203 |
+
return history
|
| 204 |
+
|
| 205 |
+
user_message = history[-1][0]
|
| 206 |
+
response = generate_response(user_message, history[:-1])
|
| 207 |
+
history[-1][1] = response
|
| 208 |
+
return history
|
| 209 |
+
|
| 210 |
+
msg.submit(user, [msg, chatbot], [msg, chatbot], queue=False).then(
|
| 211 |
+
bot, chatbot, chatbot
|
| 212 |
+
)
|
| 213 |
+
submit_btn.click(user, [msg, chatbot], [msg, chatbot], queue=False).then(
|
| 214 |
+
bot, chatbot, chatbot
|
| 215 |
+
)
|
| 216 |
+
clear_btn.click(lambda: None, None, chatbot, queue=False)
|
| 217 |
+
|
| 218 |
+
return demo
|
| 219 |
+
|
| 220 |
+
if __name__ == "__main__":
|
| 221 |
+
demo = create_interface()
|
| 222 |
+
demo.launch(server_name="0.0.0.0", server_port=7860, share=False)
|
| 223 |
+
|
app_hf_inference.py
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Hugging Face Inference APIを使用する軽量版
|
| 3 |
+
このバージョンはモデルをローカルにダウンロードせず、Hugging FaceのInference APIを使用します
|
| 4 |
+
"""
|
| 5 |
+
import gradio as gr
|
| 6 |
+
import os
|
| 7 |
+
import requests
|
| 8 |
+
|
| 9 |
+
# Hugging Face Inference APIの設定
|
| 10 |
+
HF_API_URL = os.getenv("HF_API_URL", "https://api-inference.huggingface.co/models/elyza/ELYZA-japanese-Llama-2-7b-instruct")
|
| 11 |
+
HF_API_TOKEN = os.getenv("HF_API_TOKEN", "")
|
| 12 |
+
|
| 13 |
+
# 优化的System Prompt
|
| 14 |
+
SYSTEM_PROMPT = """あなたは農業推進事業者です。農家さんの質問や懸念に対して、共感的で具体的な回答をしてください。
|
| 15 |
+
|
| 16 |
+
回答のスタイル:
|
| 17 |
+
- 親しみやすい口語体を使う(「おじさん」「俺」「だよね」など)
|
| 18 |
+
- 農家さんの気持ちに共感する(「そうだよね」「心配だよね」「分かる分かる」など)
|
| 19 |
+
- 具体的な例や実際の経験を挙げる(「去年参加した○○さん」「実際にやってみると」など)
|
| 20 |
+
- 技術的な専門用語や統計データは避ける
|
| 21 |
+
- 柔軟な解決策を提案する
|
| 22 |
+
- 日常的な言葉や比喩を使う
|
| 23 |
+
- 農家さんを尊重し、強制しない姿勢を示す
|
| 24 |
+
- 実践的で分かりやすい説明をする
|
| 25 |
+
|
| 26 |
+
以下のような表現を避ける:
|
| 27 |
+
- 「統計的に見て」「データによれば」「科学的根拠に基づき」などの専門的表現
|
| 28 |
+
- 「推奨いたします」「必要となります」などの硬い敬語
|
| 29 |
+
- 数値やパーセンテージを多用する説明
|
| 30 |
+
|
| 31 |
+
代わりに、以下のような表現を使う:
|
| 32 |
+
- 「実際にやってみると」「去年のデータ見ても」
|
| 33 |
+
- 「一緒にやってみようよ」「相談しようね」
|
| 34 |
+
- 「大丈夫だよ」「安心して」などの安心感を与える言葉"""
|
| 35 |
+
|
| 36 |
+
def format_prompt(user_message, history=None):
|
| 37 |
+
"""格式化提示词"""
|
| 38 |
+
conversation = ""
|
| 39 |
+
if history:
|
| 40 |
+
for user_msg, assistant_msg in history:
|
| 41 |
+
if assistant_msg:
|
| 42 |
+
conversation += f"ユーザー: {user_msg}\nアシスタント: {assistant_msg}\n\n"
|
| 43 |
+
|
| 44 |
+
full_message = conversation + f"ユーザー: {user_message}\nアシスタント: "
|
| 45 |
+
|
| 46 |
+
prompt = f"""<s>[INST] <<SYS>>
|
| 47 |
+
{SYSTEM_PROMPT}
|
| 48 |
+
<</SYS>>
|
| 49 |
+
|
| 50 |
+
{full_message} [/INST]"""
|
| 51 |
+
return prompt
|
| 52 |
+
|
| 53 |
+
def generate_response(message, history):
|
| 54 |
+
"""使用Hugging Face Inference API生成回答"""
|
| 55 |
+
prompt = format_prompt(message, history)
|
| 56 |
+
|
| 57 |
+
headers = {}
|
| 58 |
+
if HF_API_TOKEN:
|
| 59 |
+
headers["Authorization"] = f"Bearer {HF_API_TOKEN}"
|
| 60 |
+
|
| 61 |
+
payload = {
|
| 62 |
+
"inputs": prompt,
|
| 63 |
+
"parameters": {
|
| 64 |
+
"max_new_tokens": 512,
|
| 65 |
+
"temperature": 0.7,
|
| 66 |
+
"top_p": 0.9,
|
| 67 |
+
"do_sample": True,
|
| 68 |
+
"return_full_text": False,
|
| 69 |
+
},
|
| 70 |
+
"options": {
|
| 71 |
+
"wait_for_model": True
|
| 72 |
+
}
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
try:
|
| 76 |
+
response = requests.post(HF_API_URL, headers=headers, json=payload, timeout=60)
|
| 77 |
+
response.raise_for_status()
|
| 78 |
+
|
| 79 |
+
result = response.json()
|
| 80 |
+
|
| 81 |
+
if isinstance(result, list) and len(result) > 0:
|
| 82 |
+
generated_text = result[0].get("generated_text", "")
|
| 83 |
+
# 清理回答
|
| 84 |
+
generated_text = generated_text.strip()
|
| 85 |
+
# 移除可能的重复提示词
|
| 86 |
+
if "[/INST]" in generated_text:
|
| 87 |
+
generated_text = generated_text.split("[/INST]")[-1].strip()
|
| 88 |
+
return generated_text
|
| 89 |
+
else:
|
| 90 |
+
return "申し訳ございませんが、回答を生成できませんでした。もう一度お試しください。"
|
| 91 |
+
|
| 92 |
+
except requests.exceptions.RequestException as e:
|
| 93 |
+
return f"APIリクエストエラー: {str(e)}。もう一度お試しください。"
|
| 94 |
+
except Exception as e:
|
| 95 |
+
return f"エラーが発生しました: {str(e)}"
|
| 96 |
+
|
| 97 |
+
# 创建Gradio界面
|
| 98 |
+
def create_interface():
|
| 99 |
+
with gr.Blocks(title="農業相談チャットボット", theme=gr.themes.Soft()) as demo:
|
| 100 |
+
gr.Markdown("""
|
| 101 |
+
# 🌾 農業相談チャットボット
|
| 102 |
+
|
| 103 |
+
農家さんの質問や懸念に対して、親しみやすく分かりやすい回答をします。
|
| 104 |
+
農業に関する質問を気軽にどうぞ!
|
| 105 |
+
|
| 106 |
+
**注意**: このバージョンはHugging Face Inference APIを使用しています。
|
| 107 |
+
""")
|
| 108 |
+
|
| 109 |
+
chatbot = gr.Chatbot(
|
| 110 |
+
label="チャット",
|
| 111 |
+
height=500,
|
| 112 |
+
show_copy_button=True
|
| 113 |
+
)
|
| 114 |
+
|
| 115 |
+
with gr.Row():
|
| 116 |
+
msg = gr.Textbox(
|
| 117 |
+
label="メッセージ",
|
| 118 |
+
placeholder="農業に関する質問を入力してください...",
|
| 119 |
+
scale=4,
|
| 120 |
+
lines=2
|
| 121 |
+
)
|
| 122 |
+
submit_btn = gr.Button("送信", variant="primary", scale=1)
|
| 123 |
+
|
| 124 |
+
with gr.Row():
|
| 125 |
+
clear_btn = gr.Button("会話をクリア", variant="secondary")
|
| 126 |
+
|
| 127 |
+
# 示例问题
|
| 128 |
+
gr.Markdown("### 💡 質問例")
|
| 129 |
+
examples = gr.Examples(
|
| 130 |
+
examples=[
|
| 131 |
+
"中干期を延ばすと米がパサパサになるって聞いたんだけど、そんなリスクは取りたくないんだよ。",
|
| 132 |
+
"収量が減ったらどうするんだ?家族を養っていかなきゃならないんだよ。",
|
| 133 |
+
"水の管理が難しくなるんじゃないか?今でも大変なのに。",
|
| 134 |
+
"高齢で体力に自信がないんだ。新しいことを覚えられるかな。",
|
| 135 |
+
],
|
| 136 |
+
inputs=msg,
|
| 137 |
+
label="クリックして試してみてください"
|
| 138 |
+
)
|
| 139 |
+
|
| 140 |
+
# 事件处理
|
| 141 |
+
def user(user_message, history):
|
| 142 |
+
return "", history + [[user_message, None]]
|
| 143 |
+
|
| 144 |
+
def bot(history):
|
| 145 |
+
if not history or not history[-1][0]:
|
| 146 |
+
return history
|
| 147 |
+
|
| 148 |
+
user_message = history[-1][0]
|
| 149 |
+
response = generate_response(user_message, history[:-1])
|
| 150 |
+
history[-1][1] = response
|
| 151 |
+
return history
|
| 152 |
+
|
| 153 |
+
msg.submit(user, [msg, chatbot], [msg, chatbot], queue=False).then(
|
| 154 |
+
bot, chatbot, chatbot
|
| 155 |
+
)
|
| 156 |
+
submit_btn.click(user, [msg, chatbot], [msg, chatbot], queue=False).then(
|
| 157 |
+
bot, chatbot, chatbot
|
| 158 |
+
)
|
| 159 |
+
clear_btn.click(lambda: None, None, chatbot, queue=False)
|
| 160 |
+
|
| 161 |
+
return demo
|
| 162 |
+
|
| 163 |
+
if __name__ == "__main__":
|
| 164 |
+
demo = create_interface()
|
| 165 |
+
demo.launch(server_name="0.0.0.0", server_port=7860, share=False)
|
| 166 |
+
|
config.json
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"model_name": "elyza/ELYZA-japanese-Llama-2-7b-instruct",
|
| 3 |
+
"max_new_tokens": 512,
|
| 4 |
+
"temperature": 0.7,
|
| 5 |
+
"top_p": 0.9,
|
| 6 |
+
"system_prompt_file": "system_prompt.txt"
|
| 7 |
+
}
|
| 8 |
+
|
requirements.txt
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
gradio>=4.0.0
|
| 2 |
+
transformers>=4.35.0
|
| 3 |
+
torch>=2.0.0
|
| 4 |
+
accelerate>=0.24.0
|
| 5 |
+
sentencepiece>=0.1.99
|
| 6 |
+
requests>=2.31.0
|
| 7 |
+
|
system_prompt.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
あなたは農業推進事業者です。農家さんの質問や懸念に対して、共感的で具体的な回答をしてください。
|
| 2 |
+
|
| 3 |
+
回答のスタイル:
|
| 4 |
+
- 親しみやすい口語体を使う(「おじさん」「俺」「だよね」など)
|
| 5 |
+
- 農家さんの気持ちに共感する(「そうだよね」「心配だよね」「分かる分かる」など)
|
| 6 |
+
- 具体的な例や実際の経験を挙げる(「去年参加した○○さん」「実際にやってみると」など)
|
| 7 |
+
- 技術的な専門用語や統計データは避ける
|
| 8 |
+
- 柔軟な解決策を提案する
|
| 9 |
+
- 日常的な言葉や比喩を使う
|
| 10 |
+
- 農家さんを尊重し、強制しない姿勢を示す
|
| 11 |
+
- 実践的で分かりやすい説明をする
|
| 12 |
+
|
| 13 |
+
以下のような表現を避ける:
|
| 14 |
+
- 「統計的に見て」「データによれば」「科学的根拠に基づき」などの専門的表現
|
| 15 |
+
- 「推奨いたします」「必要となります」などの硬い敬語
|
| 16 |
+
- 数値やパーセンテージを多用する説明
|
| 17 |
+
|
| 18 |
+
代わりに、以下のような表現を使う:
|
| 19 |
+
- 「実際にやってみると」「去年のデータ見ても」
|
| 20 |
+
- 「一緒にやってみようよ」「相談しようね」
|
| 21 |
+
- 「大丈夫だよ」「安心して」などの安心感を与える言葉
|
| 22 |
+
|