Skip to content

Commit 8a3bc96

Browse files
author
覃蔚
committed
Add EPO codebase
1 parent a948907 commit 8a3bc96

File tree

1,169 files changed

+154952
-35
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,169 files changed

+154952
-35
lines changed

Alfshop/.gitignore

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# C extensions
7+
*.so
8+
9+
# Distribution / packaging
10+
.Python
11+
build/
12+
develop-eggs/
13+
dist/
14+
downloads/
15+
eggs/
16+
.eggs/
17+
lib/
18+
lib64/
19+
parts/
20+
sdist/
21+
var/
22+
wheels/
23+
share/python-wheels/
24+
*.egg-info/
25+
.installed.cfg
26+
*.egg
27+
MANIFEST
28+
29+
# PyInstaller
30+
# Usually these files are written by a python script from a template
31+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
32+
*.manifest
33+
*.spec
34+
35+
# Installer logs
36+
pip-log.txt
37+
pip-delete-this-directory.txt
38+
39+
# Unit test / coverage reports
40+
htmlcov/
41+
.tox/
42+
.nox/
43+
.coverage
44+
.coverage.*
45+
.cache
46+
nosetests.xml
47+
coverage.xml
48+
*.cover
49+
*.py,cover
50+
.hypothesis/
51+
.pytest_cache/
52+
cover/
53+
54+
# Translations
55+
*.mo
56+
*.pot
57+
58+
# Django stuff:
59+
*.log
60+
local_settings.py
61+
db.sqlite3
62+
db.sqlite3-journal
63+
64+
# Flask stuff:
65+
instance/
66+
.webassets-cache
67+
68+
# Scrapy stuff:
69+
.scrapy
70+
71+
# Sphinx documentation
72+
docs/_build/
73+
74+
# PyBuilder
75+
.pybuilder/
76+
target/
77+
78+
# Jupyter Notebook
79+
.ipynb_checkpoints
80+
81+
# IPython
82+
profile_default/
83+
ipython_config.py
84+
85+
# pyenv
86+
# For a library or package, you might want to ignore these files since the code is
87+
# intended to run in multiple environments; otherwise, check them in:
88+
# .python-version
89+
90+
# pipenv
91+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
93+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
94+
# install all needed dependencies.
95+
#Pipfile.lock
96+
97+
# poetry
98+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
99+
# This is especially recommended for binary packages to ensure reproducibility, and is more
100+
# commonly ignored for libraries.
101+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
102+
#poetry.lock
103+
104+
# pdm
105+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
106+
#pdm.lock
107+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
108+
# in version control.
109+
# https://pdm.fming.dev/#use-with-ide
110+
.pdm.toml
111+
112+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
113+
__pypackages__/
114+
115+
# Celery stuff
116+
celerybeat-schedule
117+
celerybeat.pid
118+
119+
# SageMath parsed files
120+
*.sage.py
121+
122+
# Environments
123+
.env
124+
.venv
125+
env/
126+
venv/
127+
ENV/
128+
env.bak/
129+
venv.bak/
130+
131+
# Spyder project settings
132+
.spyderproject
133+
.spyproject
134+
135+
# Rope project settings
136+
.ropeproject
137+
138+
# mkdocs documentation
139+
/site
140+
141+
# mypy
142+
.mypy_cache/
143+
.dmypy.json
144+
dmypy.json
145+
146+
# Pyre type checker
147+
.pyre/
148+
149+
# pytype static type analyzer
150+
.pytype/
151+
152+
# Cython debug symbols
153+
cython_debug/
154+
155+
# PyCharm
156+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
157+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
158+
# and can be added to the global gitignore or merged into this file. For a more nuclear
159+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
160+
.idea/
161+
.vscode/
162+
163+
*.zip
164+
envs/webshop/data/
165+
envs/webshop/search_index/
166+
/data/
167+
test.sh
168+
eval_agent/data/alfworld/json_2.1.1/

Alfshop/README.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Evaluation on WebShop and ALFWorld
2+
3+
We build our WebShop and ALFWorld implementation on top of [EPO] (https://github.com/Yifan-Song793/ETO/tree/main).
4+
5+
6+
## Structure
7+
8+
There are three main folders in this directory: `envs`, `eval_agent`, `fastchat`
9+
10+
`envs`: the interaction environment of WebShop. We transform the original [WebShop](https://github.com/princeton-nlp/WebShop) repo into a package.
11+
12+
`eval_agent`: the evaluation framework of agent tasks, which is inspired by [MINT](https://github.com/xingyaoww/mint-bench).
13+
14+
`fastchat`: training scripts for EPO, which is a modified version of [FastChat](https://github.com/lm-sys/FastChat).
15+
16+
17+
## Setup
18+
19+
```bash
20+
bash setup.sh
21+
```
22+
23+
The setup script performs the following actions:
24+
25+
- Install Python dependencies for agent training, deployment, evaluation, and the environments for WebShop, ALFWorld
26+
- Download data and search engine indices for WebShop
27+
- Download game files for ALFWorld
28+
29+
30+
## Evaluation with a strategic reasoning model
31+
32+
First, launch the controller of FastChat
33+
```bash
34+
python -m fastchat.serve.controller
35+
```
36+
37+
Then, launch the model worker of FastChat
38+
```bash
39+
python -m fastchat.serve.model_worker --model-path <YOUR_MODEL_PATH> --port 21002 --worker-address http://localhost:21002
40+
```
41+
42+
Finally, evaluate the agent
43+
```bash
44+
python -m eval_agent.main --thought_agent_config fastchat --thought_model_name <REASON_MODEL_NAME> --action_agent_config openai --action_model_name <ACTION_MODEL_NAME> --exp_config <TASK_NAME> --split test --verbose
45+
```
46+
47+
48+
## ⚙️ How to Add a New Task
49+
50+
1. Implement your task loader in `eval_agent/tasks`. You should implement the `load_tasks` method which returns a task generator.
51+
2. Implement the corresponding environment in `eval_agent/envs`. The environment should parse the action generated by the LLM agent, execute the action, and return the observation. The tool/API calling should also be implemented in the environment.
52+
3. Write the instruction prompt and ICL examples in `eval_agent/prompt`. The default setting is 1-shot evaluation.
53+
4. Write a new task config in `eval_agent/configs/task`. The config defines which task class and environment class to load, and the settings of the environment (e.g., max action steps).

Alfshop/envs/webshop/setup.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from setuptools import setup, find_packages
2+
3+
setup(
4+
name='webshop',
5+
version='0.1',
6+
packages=find_packages('src'),
7+
package_dir={'': 'src'},
8+
install_requires=[
9+
"beautifulsoup4==4.11.1",
10+
"cleantext==1.1.4",
11+
"env==0.1.0",
12+
"faiss-cpu==1.7.4",
13+
"Flask==2.1.2",
14+
"gym==0.24.0",
15+
"pyserini==0.17.0",
16+
"pytest",
17+
"rank_bm25==0.2.2",
18+
"requests_mock",
19+
"scikit_learn==1.1.1",
20+
"selenium==4.2.0",
21+
"spacy==3.6.1",
22+
"thinc==8.1.12",
23+
"thefuzz==0.20.0",
24+
"werkzeug==2.3.8",
25+
],
26+
author='Your Name',
27+
author_email='[email protected]',
28+
description='webshop pip package version',
29+
license='MIT',
30+
keywords='sample setuptools development',
31+
url='https://github.com/yourusername/mypackage'
32+
)

Alfshop/envs/webshop/src/webshop/__init__.py

Whitespace-only changes.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"""
2+
Test the site gym environment.
3+
4+
TODO: move to testing dir for more rigorous tests
5+
"""
6+
import gym
7+
from rich import print
8+
from rich.markup import escape
9+
10+
from ..web_agent_site.envs import WebAgentSiteEnv
11+
from ..web_agent_site.models import (
12+
HumanPolicy,
13+
RandomPolicy,
14+
)
15+
from ..web_agent_site.utils import DEBUG_PROD_SIZE
16+
17+
18+
if __name__ == '__main__':
19+
#env = gym.make('WebAgentSite-v0')
20+
#env = WebAgentSiteEnv(render=True, pause=2.0)
21+
#env = WebAgentSiteEnv(observation_mode='html', render=False)
22+
env = WebAgentSiteEnv(observation_mode='text', render=False, num_products=DEBUG_PROD_SIZE)
23+
global_step = 0
24+
25+
try:
26+
#policy = HumanPolicy()
27+
policy = RandomPolicy()
28+
29+
observation = env.observation
30+
while True:
31+
print(observation)
32+
available_actions = env.get_available_actions()
33+
print('Available actions:', available_actions)
34+
action = policy.forward(observation, available_actions)
35+
observation, reward, done, info = env.step(action)
36+
print(f'Taking action "{escape(action)}" -> Reward = {reward}')
37+
if done:
38+
break
39+
global_step += 1
40+
finally:
41+
env.close()
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""
2+
Test the text gym environment.
3+
4+
TODO: move to testing dir for more rigorous tests
5+
"""
6+
import gym
7+
from rich import print
8+
from rich.markup import escape
9+
10+
from web_agent_site.envs import WebAgentTextEnv
11+
from web_agent_site.models import RandomPolicy
12+
from web_agent_site.utils import DEBUG_PROD_SIZE
13+
14+
if __name__ == '__main__':
15+
env = gym.make('WebAgentTextEnv-v0', observation_mode='text', num_products=DEBUG_PROD_SIZE)
16+
env.reset()
17+
18+
try:
19+
policy = RandomPolicy()
20+
21+
observation = env.observation
22+
while True:
23+
print(observation)
24+
available_actions = env.get_available_actions()
25+
print('Available actions:', available_actions)
26+
action = policy.forward(observation, available_actions)
27+
observation, reward, done, info = env.step(action)
28+
print(f'Taking action "{escape(action)}" -> Reward = {reward}')
29+
if done:
30+
break
31+
finally:
32+
env.close()
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import json
2+
from pyserini.search.lucene import LuceneSearcher
3+
from rich import print
4+
5+
6+
searcher = LuceneSearcher('indexes')
7+
hits = searcher.search('rubber sole shoes', k=20)
8+
9+
for hit in hits:
10+
doc = searcher.doc(hit.docid)
11+
print(doc)
12+
obj = json.loads(doc.raw())['product']['Title']
13+
print(obj)
14+
15+
print(len(hits))
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Sim-to-real Transfer
2+
This folder contains code for transferring agents trained on WebShop to perform on third party websites, specifically [Amazon](http://amazon.com) and [eBay](http://ebay.com). The imitation learning and reinforcement learning agents exercised by the transfer code can be found on WebShop's Hugging Face [page](https://huggingface.co/webshop).
3+
4+
Interact with a demo of the transfer code, deployed as a 🤗 Hugging Face space [here](https://huggingface.co/spaces/webshop/amazon_shop)!
5+
6+
## 🛠️ Usage
7+
The Gradio app deployed as the aforementioned Hugging Face space can be started locally by running `python app.py` in this folder. The initial `setup.sh` script should have installed all the required dependencies.
8+
9+
## ➡️ Transfer Logic
10+
The Sim-to-real transfer code follows this general logical flow:
11+
12+
<img src="../assets/transfer-logic.png" width="100%">
13+
14+
The contents of this directory each serve the following purposes:
15+
* `app.py`: Run to launch interactive [Gradio](https://gradio.app/) demo of app
16+
* `predict_help.py`: Amazon, eBay web scraping code
17+
* `webshop_lite.py`: A condensed version of WebShop's templating engine
18+
19+
If you are interested in *transferring an agent's functionality to an new website or platform*, you will need to...
20+
1. implement two new functions: `parse_results_<platform>.py` and `parse_item_page_<platform>.py`. The corresponding interfaces and working examples for Amazon can be found [here](https://github.com/princeton-nlp/webshop/tree/master/transfer/predict_help.py#L262) and [here](https://github.com/princeton-nlp/webshop/tree/master/transfer/predict_help.py#L296).
21+
2. Invoke these functions in the [`run_episode`](https://github.com/princeton-nlp/webshop/tree/master/transfer/app.py#L105) function in the `app.py` file. Specifically, you should add a single call to...
22+
* `parse_results...` in the [conditional]((https://github.com/princeton-nlp/webshop/tree/master/transfer/predict_help.py#L220)) handling `Page.RESULTS` page types
23+
* `parse_item_page...` in the [conditional]((https://github.com/princeton-nlp/webshop/tree/master/transfer/predict_help.py#L240)) handling `Page.ITEMS` page types

Alfshop/envs/webshop/src/webshop/transfer/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)