Spaces:
Running
on
Zero
Running
on
Zero
| Metadata-Version: 2.4 | |
| Name: ether0 | |
| Version: 0.0.0 | |
| Summary: Data models, rewards, and utility functions for ether0. | |
| Author-email: FutureHouse technical staff <hello@futurehouse.org> | |
| License: Apache License | |
| Version 2.0, January 2004 | |
| http://www.apache.org/licenses/ | |
| TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | |
| 1. Definitions. | |
| "License" shall mean the terms and conditions for use, reproduction, | |
| and distribution as defined by Sections 1 through 9 of this document. | |
| "Licensor" shall mean the copyright owner or entity authorized by | |
| the copyright owner that is granting the License. | |
| "Legal Entity" shall mean the union of the acting entity and all | |
| other entities that control, are controlled by, or are under common | |
| control with that entity. For the purposes of this definition, | |
| "control" means (i) the power, direct or indirect, to cause the | |
| direction or management of such entity, whether by contract or | |
| otherwise, or (ii) ownership of fifty percent (50%) or more of the | |
| outstanding shares, or (iii) beneficial ownership of such entity. | |
| "You" (or "Your") shall mean an individual or Legal Entity | |
| exercising permissions granted by this License. | |
| "Source" form shall mean the preferred form for making modifications, | |
| including but not limited to software source code, documentation | |
| source, and configuration files. | |
| "Object" form shall mean any form resulting from mechanical | |
| transformation or translation of a Source form, including but | |
| not limited to compiled object code, generated documentation, | |
| and conversions to other media types. | |
| "Work" shall mean the work of authorship, whether in Source or | |
| Object form, made available under the License, as indicated by a | |
| copyright notice that is included in or attached to the work | |
| (an example is provided in the Appendix below). | |
| "Derivative Works" shall mean any work, whether in Source or Object | |
| form, that is based on (or derived from) the Work and for which the | |
| editorial revisions, annotations, elaborations, or other modifications | |
| represent, as a whole, an original work of authorship. For the purposes | |
| of this License, Derivative Works shall not include works that remain | |
| separable from, or merely link (or bind by name) to the interfaces of, | |
| the Work and Derivative Works thereof. | |
| "Contribution" shall mean any work of authorship, including | |
| the original version of the Work and any modifications or additions | |
| to that Work or Derivative Works thereof, that is intentionally | |
| submitted to Licensor for inclusion in the Work by the copyright owner | |
| or by an individual or Legal Entity authorized to submit on behalf of | |
| the copyright owner. For the purposes of this definition, "submitted" | |
| means any form of electronic, verbal, or written communication sent | |
| to the Licensor or its representatives, including but not limited to | |
| communication on electronic mailing lists, source code control systems, | |
| and issue tracking systems that are managed by, or on behalf of, the | |
| Licensor for the purpose of discussing and improving the Work, but | |
| excluding communication that is conspicuously marked or otherwise | |
| designated in writing by the copyright owner as "Not a Contribution." | |
| "Contributor" shall mean Licensor and any individual or Legal Entity | |
| on behalf of whom a Contribution has been received by Licensor and | |
| subsequently incorporated within the Work. | |
| 2. Grant of Copyright License. Subject to the terms and conditions of | |
| this License, each Contributor hereby grants to You a perpetual, | |
| worldwide, non-exclusive, no-charge, royalty-free, irrevocable | |
| copyright license to reproduce, prepare Derivative Works of, | |
| publicly display, publicly perform, sublicense, and distribute the | |
| Work and such Derivative Works in Source or Object form. | |
| 3. Grant of Patent License. Subject to the terms and conditions of | |
| this License, each Contributor hereby grants to You a perpetual, | |
| worldwide, non-exclusive, no-charge, royalty-free, irrevocable | |
| (except as stated in this section) patent license to make, have made, | |
| use, offer to sell, sell, import, and otherwise transfer the Work, | |
| where such license applies only to those patent claims licensable | |
| by such Contributor that are necessarily infringed by their | |
| Contribution(s) alone or by combination of their Contribution(s) | |
| with the Work to which such Contribution(s) was submitted. If You | |
| institute patent litigation against any entity (including a | |
| cross-claim or counterclaim in a lawsuit) alleging that the Work | |
| or a Contribution incorporated within the Work constitutes direct | |
| or contributory patent infringement, then any patent licenses | |
| granted to You under this License for that Work shall terminate | |
| as of the date such litigation is filed. | |
| 4. Redistribution. You may reproduce and distribute copies of the | |
| Work or Derivative Works thereof in any medium, with or without | |
| modifications, and in Source or Object form, provided that You | |
| meet the following conditions: | |
| (a) You must give any other recipients of the Work or | |
| Derivative Works a copy of this License; and | |
| (b) You must cause any modified files to carry prominent notices | |
| stating that You changed the files; and | |
| (c) You must retain, in the Source form of any Derivative Works | |
| that You distribute, all copyright, patent, trademark, and | |
| attribution notices from the Source form of the Work, | |
| excluding those notices that do not pertain to any part of | |
| the Derivative Works; and | |
| (d) If the Work includes a "NOTICE" text file as part of its | |
| distribution, then any Derivative Works that You distribute must | |
| include a readable copy of the attribution notices contained | |
| within such NOTICE file, excluding those notices that do not | |
| pertain to any part of the Derivative Works, in at least one | |
| of the following places: within a NOTICE text file distributed | |
| as part of the Derivative Works; within the Source form or | |
| documentation, if provided along with the Derivative Works; or, | |
| within a display generated by the Derivative Works, if and | |
| wherever such third-party notices normally appear. The contents | |
| of the NOTICE file are for informational purposes only and | |
| do not modify the License. You may add Your own attribution | |
| notices within Derivative Works that You distribute, alongside | |
| or as an addendum to the NOTICE text from the Work, provided | |
| that such additional attribution notices cannot be construed | |
| as modifying the License. | |
| You may add Your own copyright statement to Your modifications and | |
| may provide additional or different license terms and conditions | |
| for use, reproduction, or distribution of Your modifications, or | |
| for any such Derivative Works as a whole, provided Your use, | |
| reproduction, and distribution of the Work otherwise complies with | |
| the conditions stated in this License. | |
| 5. Submission of Contributions. Unless You explicitly state otherwise, | |
| any Contribution intentionally submitted for inclusion in the Work | |
| by You to the Licensor shall be under the terms and conditions of | |
| this License, without any additional terms or conditions. | |
| Notwithstanding the above, nothing herein shall supersede or modify | |
| the terms of any separate license agreement you may have executed | |
| with Licensor regarding such Contributions. | |
| 6. Trademarks. This License does not grant permission to use the trade | |
| names, trademarks, service marks, or product names of the Licensor, | |
| except as required for reasonable and customary use in describing the | |
| origin of the Work and reproducing the content of the NOTICE file. | |
| 7. Disclaimer of Warranty. Unless required by applicable law or | |
| agreed to in writing, Licensor provides the Work (and each | |
| Contributor provides its Contributions) on an "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |
| implied, including, without limitation, any warranties or conditions | |
| of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | |
| PARTICULAR PURPOSE. You are solely responsible for determining the | |
| appropriateness of using or redistributing the Work and assume any | |
| risks associated with Your exercise of permissions under this License. | |
| 8. Limitation of Liability. In no event and under no legal theory, | |
| whether in tort (including negligence), contract, or otherwise, | |
| unless required by applicable law (such as deliberate and grossly | |
| negligent acts) or agreed to in writing, shall any Contributor be | |
| liable to You for damages, including any direct, indirect, special, | |
| incidental, or consequential damages of any character arising as a | |
| result of this License or out of the use or inability to use the | |
| Work (including but not limited to damages for loss of goodwill, | |
| work stoppage, computer failure or malfunction, or any and all | |
| other commercial damages or losses), even if such Contributor | |
| has been advised of the possibility of such damages. | |
| 9. Accepting Warranty or Additional Liability. While redistributing | |
| the Work or Derivative Works thereof, You may choose to offer, | |
| and charge a fee for, acceptance of support, warranty, indemnity, | |
| or other liability obligations and/or rights consistent with this | |
| License. However, in accepting such obligations, You may act only | |
| on Your own behalf and on Your sole responsibility, not on behalf | |
| of any other Contributor, and only if You agree to indemnify, | |
| defend, and hold each Contributor harmless for any liability | |
| incurred by, or claims asserted against, such Contributor by reason | |
| of your accepting any such warranty or additional liability. | |
| END OF TERMS AND CONDITIONS | |
| APPENDIX: How to apply the Apache License to your work. | |
| To apply the Apache License to your work, attach the following | |
| boilerplate notice, with the fields enclosed by brackets "[]" | |
| replaced with your own identifying information. (Don't include | |
| the brackets!) The text should be enclosed in the appropriate | |
| comment syntax for the file format. We also recommend that a | |
| file or class name and description of purpose be included on the | |
| same "printed page" as the copyright notice for easier | |
| identification within third-party archives. | |
| Copyright 2025 FutureHouse | |
| Licensed under the Apache License, Version 2.0 (the "License"); | |
| you may not use this file except in compliance with the License. | |
| You may obtain a copy of the License at | |
| http://www.apache.org/licenses/LICENSE-2.0 | |
| Unless required by applicable law or agreed to in writing, software | |
| distributed under the License is distributed on an "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| See the License for the specific language governing permissions and | |
| limitations under the License. | |
| Project-URL: issues, https://github.com/Future-House/ether0/issues | |
| Project-URL: repository, https://github.com/Future-House/ether0 | |
| Classifier: Intended Audience :: Developers | |
| Classifier: License :: OSI Approved :: Apache Software License | |
| Classifier: Operating System :: OS Independent | |
| Classifier: Programming Language :: Python :: 3 :: Only | |
| Classifier: Programming Language :: Python :: 3.11 | |
| Classifier: Programming Language :: Python :: 3.12 | |
| Classifier: Programming Language :: Python :: 3.13 | |
| Classifier: Programming Language :: Python | |
| Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence | |
| Classifier: Topic :: Scientific/Engineering :: Chemistry | |
| Requires-Python: >=3.11 | |
| Description-Content-Type: text/markdown | |
| License-File: LICENSE | |
| Requires-Dist: accelerate>=1.10.1 | |
| Requires-Dist: datasets | |
| Requires-Dist: exmol>=3.3.0 | |
| Requires-Dist: gradio>=5.44.0 | |
| Requires-Dist: httpx | |
| Requires-Dist: huggingface-hub | |
| Requires-Dist: molbloom==2.3.4 | |
| Requires-Dist: pydantic>=2 | |
| Requires-Dist: rdkit | |
| Requires-Dist: regex | |
| Requires-Dist: spaces>=0.40.1 | |
| Requires-Dist: tenacity | |
| Provides-Extra: add-tokens | |
| Requires-Dist: ipykernel; extra == "add-tokens" | |
| Requires-Dist: ipywidgets>=8; extra == "add-tokens" | |
| Requires-Dist: transformers>=4.49; extra == "add-tokens" | |
| Provides-Extra: baselines | |
| Requires-Dist: fhaviary>=0.19; extra == "baselines" | |
| Requires-Dist: fhlmi>=0.26; extra == "baselines" | |
| Requires-Dist: ipython; extra == "baselines" | |
| Provides-Extra: dev | |
| Requires-Dist: ether0[add-tokens,typing]; extra == "dev" | |
| Requires-Dist: huggingface-hub[cli]; extra == "dev" | |
| Requires-Dist: ipython>=8; extra == "dev" | |
| Requires-Dist: mypy>=1.8; extra == "dev" | |
| Requires-Dist: pre-commit>=3.4; extra == "dev" | |
| Requires-Dist: pylint>=3; extra == "dev" | |
| Requires-Dist: pytest; extra == "dev" | |
| Requires-Dist: pytest-subtests; extra == "dev" | |
| Requires-Dist: pytest-sugar; extra == "dev" | |
| Requires-Dist: pytest-timer[colorama]; extra == "dev" | |
| Requires-Dist: pytest-xdist; extra == "dev" | |
| Requires-Dist: refurb>=2; extra == "dev" | |
| Requires-Dist: typeguard; extra == "dev" | |
| Provides-Extra: typing | |
| Requires-Dist: types-regex; extra == "typing" | |
| Dynamic: license-file | |
| # ether0 Reward Model | |
| [](https://github.com/Future-House/ether0) | |
| [](https://arxiv.org/abs/2506.17238) | |
| [](https://www.repostatus.org/#active) | |
|  | |
| [](https://github.com/Future-House/ether0/actions) | |
| [](https://github.com/psf/black) | |
| [](https://www.python.org) | |
| [](https://huggingface.co/futurehouse/ether0) | |
| [](https://huggingface.co/datasets/futurehouse/ether0-benchmark) | |
|  | |
| _ether0: a scientific reasoning model, dataset, and reward functions for chemistry._ | |
| This repo contains the reward model for evaluating ether0 and similar models, | |
| along with utilities for working with the verifiable rewards in | |
| [our benchmark](https://huggingface.co/datasets/futurehouse/ether0-benchmark). | |
| ## Overview | |
| ether0 is a reasoning language model post-trained through a loop of: | |
| 1. Supervised fine-tuning (SFT) on long chain-of-thought reasoning traces, | |
| to elicit reasoning from a base model. | |
| 2. Reinforcement learning with verifiable rewards (RLVR) | |
| to improve reasoning on focused task groups, at their own pace. | |
| These multitask learned models are referred to as 'specialists'. | |
| 3. Rejection sampling to filter specialists' reasoning | |
| for correctness and quality. | |
| 4. SFT on the base model again to make a 'generalist' reasoning model. | |
| 5. RLVR to recover any lost performance and push further in an all-task setting. | |
|  | |
| ### Repo Structure | |
| This repo contains several packages: | |
| - `ether0`: reward functions, `rdkit` data utilities, | |
| dataset generation prompts, dataset data models, | |
| language model training prompts, and data models. | |
| - `ether0.remotes`: server code for ether0 reward functions involving | |
| exotic packages and/or third party models. | |
| > [!NOTE] | |
| > This repo does not contain training code, | |
| > although you can find open source repositories like [NeMo-RL](https://github.com/NVIDIA/NeMo-RL) | |
| > or [Hugging Face TRL](https://github.com/huggingface/trl) | |
| > that can do the SFT and RL phases of training. | |
| ### Open Weights | |
| Please see our open-source weights on Hugging Face: | |
| <https://huggingface.co/futurehouse/ether0> | |
| ```python | |
| from transformers import AutoModelForCausalLM, AutoTokenizer | |
| model = AutoModelForCausalLM.from_pretrained("futurehouse/ether0") | |
| tokenizer = AutoTokenizer.from_pretrained("futurehouse/ether0") | |
| ``` | |
| ### Open Test Set | |
| Please see our open-source benchmark (test set) on Hugging Face: | |
| <https://huggingface.co/datasets/futurehouse/ether0-benchmark> | |
| ```python | |
| from datasets import load_dataset | |
| test_ds = load_dataset("futurehouse/ether0-benchmark", split="test") | |
| ``` | |
| ## Usage | |
| ### Installation | |
| The easiest way to get started is a `pip install` from GitHub: | |
| ```bash | |
| pip install git+https://github.com/Future-House/ether0.git | |
| ``` | |
| Or if you want the full set up, clone the repo and use `uv`: | |
| ```bash | |
| git clone https://github.com/Future-House/ether0.git | |
| cd ether0 | |
| uv sync | |
| ``` | |
| ### Reward Functions | |
| Here is a basic example of how to use the reward functions: | |
| ```python | |
| from ether0.rewards import valid_mol_eval | |
| # Task: provide a valid completion of this molecule | |
| partial_smiles = "O=C(OC1C(OC(=O)C=2C=CC=CC2)C3(O)C(C)(C)CCCC3(C)C4CC=5OC=CC5C(C)C14" | |
| # Here's two model-proposed SMILES completions | |
| invalid_completion_smiles = "CCC" | |
| valid_completion_smiles = ")C=6C=CC=CC6" | |
| # Evaluate the completions | |
| assert not valid_mol_eval(invalid_completion_smiles, partial_smiles) | |
| assert valid_mol_eval(valid_completion_smiles, partial_smiles) | |
| ``` | |
| ### Visualization | |
| If it helps, you can visualize the molecules: | |
| ```python | |
| from ether0.data import draw_molecule | |
| # See above reward functions demo for where these came from | |
| partial_smiles = "O=C(OC1C(OC(=O)C=2C=CC=CC2)C3(O)C(C)(C)CCCC3(C)C4CC=5OC=CC5C(C)C14" | |
| invalid_completion_smiles = "CCC" | |
| valid_completion_smiles = ")C=6C=CC=CC6" | |
| valid_mol_text = draw_molecule(partial_smiles + valid_completion_smiles) | |
| with open("valid_molecule.svg", "w") as f: | |
| f.write(valid_mol_text) | |
| ``` | |
| The output of `draw_molecule` can also be easily visualized using `IPython.display`, | |
| or in your terminal via `chafa valid_molecule.svg` | |
| ([chafa docs](https://hpjansson.org/chafa/)). | |
|  | |
| ### Benchmark | |
| Here is a sample baseline of | |
| [`ether0-benchmark`](https://huggingface.co/datasets/futurehouse/ether0-benchmark) | |
| on `gpt-4o` using [`lmi`](https://github.com/Future-House/ldp/tree/main/packages/lmi). | |
| To install `lmi`, please install `ether0` with the `baselines` extra | |
| (for example `uv sync --extra baselines`). | |
| We also need to run our remote rewards server via `ether0-serve` | |
| (for more information, see [`ether0.remotes` docs](packages/remotes/README.md)): | |
| ```bash | |
| ETHER0_REMOTES_API_TOKEN=abc123 ether0-serve | |
| ``` | |
| Next, start `ipython` with the relevant environment variables set: | |
| ```bash | |
| ETHER0_REMOTES_API_BASE_URL="http://127.0.0.1:8000" ETHER0_REMOTES_API_TOKEN=abc123 \ | |
| ipython | |
| ``` | |
| And run the following Python code: | |
| ```python | |
| import itertools | |
| import statistics | |
| from collections import defaultdict | |
| from aviary.core import Message | |
| from datasets import load_dataset | |
| from lmi import LiteLLMModel | |
| from tqdm.asyncio import tqdm_asyncio as asyncio | |
| from ether0.data import get_problem_category | |
| from ether0.model_prompts import LOOSE_XML_ANSWER_USER_PROMPT, extract_answer_loose | |
| from ether0.models import RewardFunctionInfo | |
| from ether0.rewards import EVAL_FUNCTIONS | |
| # Add LLM prompt of your making to the dataset | |
| test_ds = load_dataset("futurehouse/ether0-benchmark", split="test").map( | |
| lambda x: {"prompt": "\n\n".join((LOOSE_XML_ANSWER_USER_PROMPT, x["problem"]))} | |
| ) | |
| # Prompt to LLM | |
| model = LiteLLMModel(name="gpt-4o") | |
| results = await asyncio.gather( | |
| *(model.acompletion([Message(content=row["prompt"])]) for row in test_ds), | |
| desc="Running evaluation", | |
| ) | |
| # Compute rewards | |
| per_category_rewards = defaultdict(list) | |
| for row, result in zip(test_ds, results, strict=True): | |
| # NOTE: you can also use `ether0.rewards.accuracy_reward`, | |
| # but we decided to go a bit "lower level" for this demo | |
| reward_info = RewardFunctionInfo.model_validate(row["solution"]) | |
| yhat = extract_answer_loose(result[0].text) | |
| reward = EVAL_FUNCTIONS[reward_info.fxn_name]( | |
| yhat=yhat, y=reward_info.answer_info, test=True | |
| ) | |
| per_category_rewards[get_problem_category(reward_info.problem_type)].append(reward) | |
| for category, rewards in sorted(per_category_rewards.items()): | |
| print( | |
| f"In category {category!r} of {len(rewards)} questions," | |
| f" average reward was {statistics.mean(rewards):.3f}." | |
| ) | |
| accuracy = statistics.mean(itertools.chain.from_iterable(per_category_rewards.values())) | |
| print(f"Cumulative average reward across {len(test_ds)} questions was {accuracy:.3f}.") | |
| ``` | |