Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions docs/cn/open_source/evaluation/openai_memory_locomo_eval_guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# OpenAI Memory 在 LoCoMo 上的评估指南

本文档简要概述了使用 LoCoMo 数据集对 OpenAI 的 Memory 功能进行评估的整体流程。

## 1. 简介

由于 OpenAI 的 [Memory 功能](https://openai.com/index/memory-and-new-controls-for-chatgpt/) 没有公开 API,因此评估需要手动进行。LoCoMo 数据集中的对话会被格式化并手动输入到 ChatGPT 网页界面中。生成的记忆随后从账号的记忆管理页面中获取并保存到本地。

为了评估这些记忆的质量,我们将通过 API 使用 `gpt-4o-mini` 模型。模型将被问及 LoCoMo 数据集中的问题,并提供相关对话的完整记忆历史作为上下文。这模拟了一个完美的记忆检索系统,为模型提供了最佳的回答信息。

## 2. 工作流程

### 步骤 2.1:生成用于记忆提取的输入上下文

运行以下 Python 脚本,为每个对话中的每个会话生成输入提示。该脚本将为每个会话创建一个单独的 `.txt` 文件,包含格式化的对话历史和提取提示。

**脚本:**
```python
import json
import os

# 确保数据集路径正确
LOCOMO_DATA_PATH = "data/locomo/locomo10.json"
SAVE_DIR = "openai_inputs"

os.makedirs(SAVE_DIR, exist_ok=True)

TEMPLATE = """Can you please extract relevant information from this conversation and create memory entries for each user mentioned? Please store these memories in your knowledge base in addition to the timestamp provided for future reference and personalized interactions.

{context}
"""

with open(LOCOMO_DATA_PATH, "r", encoding="utf-8") as f:
data = json.load(f)

for conv_idx, item in enumerate(data):
conv = item["conversation"]

for i in range(1, 35):
session_key = f"session_{i}"
session_dt_key = f"session_{i}_date_time"
if session_key not in conv:
continue

session = conv[session_key]
session_dt = conv[session_dt_key]

session_context = ""
for chat in session:
chat_str = f"({session_dt}) {chat['speaker']}: {chat['text']}\n"
session_context += chat_str

input_string = TEMPLATE.format(context=session_context)

output_filename = os.path.join(SAVE_DIR, f"{conv_idx}-D{i}.txt")
with open(output_filename, "w", encoding="utf-8") as f:
f.write(input_string)

print(f"Generated {len(os.listdir(SAVE_DIR))} input files in '{SAVE_DIR}' directory.")
```

**输入示例(`0-D9.txt`):**
```plaintext
Can you please extract relevant information from this conversation and create memory entries for each user mentioned? Please store these memories in your knowledge base in addition to the timestamp provided for future reference and personalized interactions.

(2:31 pm on 17 July, 2023) Melanie: Hey Caroline, hope all's good! I had a quiet weekend after we went camping with my fam two weekends ago. It was great to unplug and hang with the kids. What've you been up to? Anything fun over the weekend?
(2:31 pm on 17 July, 2023) Caroline: Hey Melanie! That sounds great! Last weekend I joined a mentorship program for LGBTQ youth - it's really rewarding to help the community.
... (rest of the conversation)
```

### 步骤 2.2:从 ChatGPT 中提取并保存记忆

1. **启用记忆功能:** 在 ChatGPT 中,前往 **设置(Settings) -> 个性化(Personalization)**,确保 **记忆(Memory)** 功能已开启。
2. **清除已有记忆:** 在处理新对话之前,点击 **管理(Manage)** -> **清除全部(Clear all)**,确保清除已有记忆。
3. **输入并验证:**
* 开启一个新的聊天。
* 确保模型设置为 **GPT-4o**。
* 复制生成的 `.txt` 文件的内容(例如 `0-D1.txt`)并粘贴到聊天中。
* 模型回复后,确认看到"记忆已更新"(Memory updated)的提示。
4. **保存记忆:**
* 点击记忆确认中的 **管理(Manage)**,查看新生成的记忆。
* 创建一个与输入文件同名的新本地 `.txt` 文件(例如 `0-D1.txt`)。
* 从 ChatGPT 中复制每条记忆并粘贴到新文件中,每条记忆占一行。
5. **为下一个对话重置记忆:**
* 一个对话的所有会话完成后,务必**删除所有记忆,以确保下一个对话从干净状态开始**。前往设置(Settings) -> 个性化(Personalization) -> 管理(Manage),点击删除全部(Delete all)。

**记忆输出示例(`0-D9.txt`):**
```plaintext
As of November 17, 2023, Dave has taken up photography and enjoys capturing nature scenes like sunsets, beaches, waves, rocks, and waterfalls.
Dave recently purchased a vintage camera that takes high-quality photos.
Dave discovered a serene park nearby with a peaceful spot featuring a bench under a tree with pink flowers.
As of November 17, 2023, Calvin attended a fancy gala in Boston where he had an inspiring conversation with an artist about music and art.
Calvin finds music a powerful connector and source of creativity.
Calvin took a photo in a Japanese garden that he shared with Dave.
Calvin accepted an invitation to perform at an upcoming show in Boston, expressing excitement about the musical experience.
```

### 步骤 2.3:合并记忆

记忆目前按会话分别保存。你需要编写一个简单的脚本,将同一对话的所有记忆合并到一个文件中。例如,`0-D1.txt`、`0-D2.txt` 等文件中的所有记忆应合并为一个 `conversation_0_memories.txt` 文件。


### 步骤 2.4:自动化评估

所有对话的记忆提取并保存完成后,可以运行自动化[评估脚本](../../../../evaluation/scripts/run_openai_eval.sh)。该脚本将处理生成答案、评估答案和计算指标的过程。

```bash
# 编辑 evaluation/scripts/run_openai_eval.sh 中的配置
evaluation/scripts/run_openai_eval.sh
```

## 3. 注意事项

- **账号差异:** 请注意免费账号和 Plus 账号之间可能存在差异,例如上下文长度限制和可存储的记忆数量。
- **粒度:** 评估过程在会话级别添加记忆。为确保高质量的记忆提取,应遵循相同的原则。一次性将整个对话提供给模型已被证明效果不佳,通常会导致模型忽略重要细节,从而造成大量信息丢失。
94 changes: 94 additions & 0 deletions docs/cn/open_source/evaluation/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# 记忆评估框架

本仓库提供了使用各种模型和 API 对 `LoCoMo`、`LongMemEval`、`PrefEval`、`personaMem` 数据集进行评估的工具和脚本。


## 环境安装

1. 设置 `PYTHONPATH` 环境变量:
```bash
export PYTHONPATH=../src
cd evaluation # 请在仓库根目录执行
```

2. 安装依赖:
```bash
poetry install --extras all --with eval
```

## 配置说明
将 .env-example 文件复制一份并重命名为 .env,然后根据你的环境和 API 密钥,填写所需的环境变量。

## 安装 MemOS
### 本地服务
```bash
# 修改 {project_dir}/.env 文件并启动服务器
uvicorn memos.api.server_api:app --host 0.0.0.0 --port 8001 --workers 8

# 配置 {project_dir}/evaluation/.env 文件
MEMOS_URL="http://127.0.0.1:8001"
```
### 在线服务
```bash
# 请访问 https://memos-dashboard.openmem.net/cn/quickstart/ 获取您的 API 密钥
# 获取到API密钥后,将密钥配置到 {project_dir}/evaluation/.env 文件中
MEMOS_KEY="Token mpg-xxxxx"
MEMOS_ONLINE_URL="https://memos.memtensor.cn/api/openmem/v1"

```
## 支持的框架

脚本支持 `memos-api` 和 `memos-api-online`。同时,我们为以下记忆框架提供了非官方实现:`zep`、`mem0`、`memobase`、`supermemory`、`memu`。

## 评估脚本

### LoCoMo 评估

⚙️ 使用支持的记忆框架之一评估 **LoCoMo** 数据集 —— 运行以下脚本:

```bash
# 编辑 ./scripts/run_locomo_eval.sh 中的配置
# 指定要使用的模型和记忆后端(例如 mem0、zep 等)
evaluation/scripts/run_locomo_eval.sh
```

✍️ 如需使用 OpenAI 的原生记忆功能评估 LoCoMo 数据集,请参考详细指南:[OpenAI Memory on LoCoMo - 评估指南](./openai_memory_locomo_eval_guide.md)。

### LongMemEval 评估

首先从 https://huggingface.co/datasets/xiaowu0162/longmemeval-cleaned 下载数据集 `longmemeval_s`,并将其保存为 `data/longmemeval/longmemeval_s.json`

```bash
# 编辑 evaluation/scripts/run_lme_eval.sh 中的配置
# 指定要使用的模型和记忆后端(例如 mem0、zep 等)
evaluation/scripts/run_lme_eval.sh
```

#### 问题日期与 `reference_time`

LongMemEval 为每个问题提供了一个**问题日期**;评估时应以该日期作为“当前时间”参考,而不是运行脚本时的实际时间。LongMemEval 搜索脚本会将 `question_date` 作为 **`reference_time`** 传递给支持该参数的后端。

**MemOS Cloud** 目前不支持在搜索时提供问题日期,因此在该平台上的 LongMemEval 得分可能与完全遵循规范的运行结果存在差异。**如果需要获得可比较的数值,建议使用开源的 MemOS 服务器来评估 LongMemEval。**

### PrefEval 评估

从 https://github.com/amazon-science/PrefEval/blob/main/benchmark_dataset/filtered_inter_turns.json 下载 `benchmark_dataset/filtered_inter_turns.json`,并将其保存为 `./data/prefeval/filtered_inter_turns.json`。

要评估 **Prefeval** 数据集 —— 请运行以下脚本:

```bash
# 编辑 evaluation/scripts/run_prefeval_eval.sh 中的配置
# 指定要使用的模型和记忆后端(例如 mem0、zep 等)
evaluation/scripts/run_prefeval_eval.sh
```

### PersonaMem 评估

从 https://huggingface.co/datasets/bowen-upenn/PersonaMem 获取 `questions_32k.csv` 和 `shared_contexts_32k.jsonl`,并将其保存到 `data/personamem/` 目录下。

```bash
# 编辑 evaluation/scripts/run_pm_eval.sh 中的配置
# 指定要使用的模型和记忆后端(例如 mem0、zep 等)
# 如需使用 MIRIX,请编辑 evaluation/scripts/personamem/config.yaml 中的配置
evaluation/scripts/run_pm_eval.sh
```