treequest 0.3.2__tar.gz → 0.3.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. {treequest-0.3.2 → treequest-0.3.3}/PKG-INFO +36 -14
  2. {treequest-0.3.2 → treequest-0.3.3}/README.md +34 -12
  3. {treequest-0.3.2 → treequest-0.3.3}/pyproject.toml +9 -3
  4. treequest-0.3.3/src/treequest/algos/ab_mcts_m/_ab_mcts_m_imports.py +58 -0
  5. treequest-0.3.2/src/treequest/algos/ab_mcts_m/_ab_mcts_m_imports.py +0 -29
  6. {treequest-0.3.2 → treequest-0.3.3}/.gitignore +0 -0
  7. {treequest-0.3.2 → treequest-0.3.3}/LICENSE +0 -0
  8. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/__init__.py +0 -0
  9. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/algos/ab_mcts_a/algo.py +0 -0
  10. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/algos/ab_mcts_a/prob_state.py +0 -0
  11. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/algos/ab_mcts_m/algo.py +0 -0
  12. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/algos/ab_mcts_m/numpyro_utils.py +0 -0
  13. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/algos/ab_mcts_m/pymc_interface.py +0 -0
  14. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/algos/base.py +0 -0
  15. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/algos/best_first_search.py +0 -0
  16. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/algos/multi_armed_bandit_ucb.py +0 -0
  17. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/algos/standard_mcts.py +0 -0
  18. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/algos/tree.py +0 -0
  19. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/algos/tree_of_thought_bfs.py +0 -0
  20. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/imports.py +0 -0
  21. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/py.typed +0 -0
  22. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/ranker.py +0 -0
  23. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/trial.py +0 -0
  24. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/types.py +0 -0
  25. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/vis/__init__.py +0 -0
  26. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/vis/algo_adapters/__init__.py +0 -0
  27. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/vis/algo_adapters/ab_mcts_a.py +0 -0
  28. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/vis/algo_adapters/ab_mcts_m.py +0 -0
  29. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/vis/algo_adapters/base.py +0 -0
  30. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/vis/algo_adapters/best_first_search.py +0 -0
  31. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/vis/algo_adapters/multi_armed_bandit_ucb.py +0 -0
  32. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/vis/algo_adapters/standard_mcts.py +0 -0
  33. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/vis/algo_adapters/tree_of_thoughts_bfs.py +0 -0
  34. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/vis/assets/colormaps.json +0 -0
  35. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/vis/assets/d3.LICENSE.txt +0 -0
  36. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/vis/assets/d3.v7.min.js +0 -0
  37. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/vis/assets/d3_tree.html.jinja2 +0 -0
  38. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/vis/build_snapshot.py +0 -0
  39. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/vis/errors.py +0 -0
  40. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/vis/render.py +0 -0
  41. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/vis/renderers/__init__.py +0 -0
  42. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/vis/renderers/color_utils.py +0 -0
  43. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/vis/renderers/graphviz_renderer.py +0 -0
  44. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/vis/renderers/html.py +0 -0
  45. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/vis/renderers/json_yaml.py +0 -0
  46. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/vis/renderers/mermaid.py +0 -0
  47. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/vis/snapshot.py +0 -0
  48. {treequest-0.3.2 → treequest-0.3.3}/src/treequest/visualization.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: treequest
3
- Version: 0.3.2
3
+ Version: 0.3.3
4
4
  Summary: A Tree Search Library with Flexible API for LLM Inference-Time Scaling
5
5
  Author-email: Kou Misaki <kou.misaki@sakana.ai>, Takuya Akiba <takiba@sakana.ai>
6
6
  License-File: LICENSE
@@ -57,24 +57,27 @@ import treequest as tq
57
57
  # Each node is associated with a user-definable `state`.
58
58
  State = str
59
59
 
60
+
60
61
  # 1. Define a function to be used for node generation.
61
62
  def generate(parent_state: State | None) -> tuple[State, float]:
62
63
  """Generates new states and scores based on the parent state."""
63
- if parent_state is None: # None represents the expansion from root.
64
+ if parent_state is None: # None represents the expansion from root.
64
65
  new_state = "Initial state"
65
66
  else:
66
67
  new_state = f"State after {parent_state}"
67
68
 
68
- score = random.random() # A score for the new state; It should be normalized to the [0, 1] range.
69
+ # A score for the new state; It should be normalized to the [0, 1] range.
70
+ score = random.random()
69
71
  return new_state, score
70
72
 
73
+
71
74
  # 2. Instantiate the algorithm and a search tree object.
72
75
  algo = tq.ABMCTSA()
73
76
  search_tree = algo.init_tree()
74
77
 
75
78
  # 3. Run the search with a generation budget (10 in this case).
76
79
  for _ in range(10):
77
- search_tree = algo.step(search_tree, {'Action A': generate})
80
+ search_tree = algo.step(search_tree, {"Action A": generate})
78
81
 
79
82
  # 4. Extract the best score and state.
80
83
  best_state, best_node_score = tq.top_k(search_tree, algo, k=1)[0]
@@ -82,7 +85,8 @@ print(f"Best state: {best_state}, Score: {best_node_score}")
82
85
 
83
86
  # 5. Visualize the search tree.
84
87
  output_file_basename = Path("ab_mcts_a_search_tree")
85
- tq.render(search_tree, output_file_basename, format="html") # Generates `ab_mcts_a_search_tree.html`
88
+ # Generates `ab_mcts_a_search_tree.html`
89
+ tq.render(search_tree, output_file_basename, format="html")
86
90
  ```
87
91
 
88
92
  Alternatively, you can use an ask–tell interface with batched AB-MCTS sampling steps:
@@ -92,8 +96,9 @@ import treequest as tq
92
96
 
93
97
  State = str
94
98
 
95
- def generate(parent_state: State | None) -> tuple[State, float]:
96
- ...
99
+
100
+ def generate(parent_state: State | None) -> tuple[State, float]: ...
101
+
97
102
 
98
103
  generate_fns = {"Action A": generate}
99
104
  actions = list(generate_fns.keys())
@@ -160,11 +165,13 @@ import dataclasses
160
165
 
161
166
  import treequest as tq
162
167
 
168
+
163
169
  @dataclasses.dataclass
164
170
  class State:
165
171
  llm_answer: str
166
172
  score: float
167
173
 
174
+
168
175
  def generate(parent_state: State | None) -> tuple[State, float]:
169
176
  """Generate a new node by calling an LLM."""
170
177
  if parent_state is None:
@@ -174,12 +181,14 @@ def generate(parent_state: State | None) -> tuple[State, float]:
174
181
 
175
182
  return state, state.score
176
183
 
184
+
177
185
  def initial_generation() -> State:
178
186
  """
179
187
  Call LLM API to generate an initial answer.
180
188
  """
181
189
  ...
182
190
 
191
+
183
192
  def refine_answer(llm_answer: str, score: float) -> State:
184
193
  """
185
194
  Call LLM API to refine an answer.
@@ -190,11 +199,11 @@ def refine_answer(llm_answer: str, score: float) -> State:
190
199
  algo = tq.ABMCTSM()
191
200
  search_tree = algo.init_tree()
192
201
  for i in range(20):
193
- search_tree = algo.step(search_tree, {'Action Label': generate})
202
+ search_tree = algo.step(search_tree, {"Action Label": generate})
194
203
  # Logging best node during the search.
195
204
  if (i + 1) % 5 == 0:
196
205
  best_interim_state, _ = tq.top_k(search_tree, algo, k=1)[0]
197
- print(f"Iteration {i+1}: Best state so far = {best_interim_state}")
206
+ print(f"Iteration {i + 1}: Best state so far = {best_interim_state}")
198
207
 
199
208
  best_state, _ = tq.top_k(search_tree, algo, k=1)[0]
200
209
  print(f"Best Answer: {best_state.llm_answer}, Best Score: {best_state.score}")
@@ -209,6 +218,7 @@ from functools import partial
209
218
 
210
219
  import treequest as tq
211
220
 
221
+
212
222
  def generate(llm_name: str, parent_state=None):
213
223
  """
214
224
  Call LLM API using litellm, vllm, etc., to generate a new node
@@ -216,9 +226,12 @@ def generate(llm_name: str, parent_state=None):
216
226
  ...
217
227
  return new_state, new_score
218
228
 
229
+
219
230
  llm_names = ["o4-mini", "gemini-2.5-pro"]
220
231
  # Create dict of different actions backed by different LLMs.
221
- generate_fns = {llm_name: partial(generate, llm_name=llm_name) for llm_name in llm_names}
232
+ generate_fns = {
233
+ llm_name: partial(generate, llm_name=llm_name) for llm_name in llm_names
234
+ }
222
235
 
223
236
  algo = tq.StandardMCTS()
224
237
  search_tree = algo.init_tree()
@@ -286,10 +299,12 @@ from pathlib import Path
286
299
  import treequest as tq
287
300
  from PIL import Image
288
301
 
302
+
289
303
  class State:
290
304
  text: str
291
305
  image: Image.Image
292
306
 
307
+
293
308
  def state_formatter_html(state: State) -> str:
294
309
  """Formats the state for HTML visualization."""
295
310
  buffer = BytesIO()
@@ -299,13 +314,15 @@ def state_formatter_html(state: State) -> str:
299
314
  # In case state.text cannot be trusted, we recommend e.g., html.escape(state.text) to avoid html injection.
300
315
  return f'<p>{state.text}</p><br/><img src="data:image/webp;base64,{img_str}" width=100% />'
301
316
 
317
+
302
318
  generate_fns = {
303
319
  "action_1": ... # Define your node generation functions (actions) here
304
320
  }
305
321
 
306
322
  algo = tq.ABMCTSA()
307
323
  search_tree = algo.init_tree()
308
- output_dir = Path("search_tree"); output_dir.mkdir(exist_ok=True)
324
+ output_dir = Path("search_tree")
325
+ output_dir.mkdir(exist_ok=True)
309
326
  for i in range(10):
310
327
  search_tree = algo.step(search_tree, generate_fns)
311
328
  # Rendering "latest.html" for checking search progress on the fly
@@ -314,11 +331,16 @@ for i in range(10):
314
331
  search_tree,
315
332
  output_basename=output_dir / "latest",
316
333
  format="html",
317
- state_formatter=state_formatter_html, # Use html custom formetter
334
+ state_formatter=state_formatter_html, # Use html custom formetter
318
335
  )
319
336
 
320
337
  tq.render(search_tree, output_basename=output_dir / "final", format="pdf")
321
- tq.render(search_tree, output_basename=output_dir / "final", format="html", state_formatter=state_formatter_html)
338
+ tq.render(
339
+ search_tree,
340
+ output_basename=output_dir / "final",
341
+ format="html",
342
+ state_formatter=state_formatter_html,
343
+ )
322
344
  ```
323
345
 
324
346
  > **IMPORTANT:** When using HTML format, ensure that the HTML file is securely handled, especially if the state formatter includes raw HTML content. Avoid opening untrusted HTML files in your browser. For example, XSS (cross site scripting) attacks can occur if the state includes malicious HTML/JavaScript code.
@@ -21,24 +21,27 @@ import treequest as tq
21
21
  # Each node is associated with a user-definable `state`.
22
22
  State = str
23
23
 
24
+
24
25
  # 1. Define a function to be used for node generation.
25
26
  def generate(parent_state: State | None) -> tuple[State, float]:
26
27
  """Generates new states and scores based on the parent state."""
27
- if parent_state is None: # None represents the expansion from root.
28
+ if parent_state is None: # None represents the expansion from root.
28
29
  new_state = "Initial state"
29
30
  else:
30
31
  new_state = f"State after {parent_state}"
31
32
 
32
- score = random.random() # A score for the new state; It should be normalized to the [0, 1] range.
33
+ # A score for the new state; It should be normalized to the [0, 1] range.
34
+ score = random.random()
33
35
  return new_state, score
34
36
 
37
+
35
38
  # 2. Instantiate the algorithm and a search tree object.
36
39
  algo = tq.ABMCTSA()
37
40
  search_tree = algo.init_tree()
38
41
 
39
42
  # 3. Run the search with a generation budget (10 in this case).
40
43
  for _ in range(10):
41
- search_tree = algo.step(search_tree, {'Action A': generate})
44
+ search_tree = algo.step(search_tree, {"Action A": generate})
42
45
 
43
46
  # 4. Extract the best score and state.
44
47
  best_state, best_node_score = tq.top_k(search_tree, algo, k=1)[0]
@@ -46,7 +49,8 @@ print(f"Best state: {best_state}, Score: {best_node_score}")
46
49
 
47
50
  # 5. Visualize the search tree.
48
51
  output_file_basename = Path("ab_mcts_a_search_tree")
49
- tq.render(search_tree, output_file_basename, format="html") # Generates `ab_mcts_a_search_tree.html`
52
+ # Generates `ab_mcts_a_search_tree.html`
53
+ tq.render(search_tree, output_file_basename, format="html")
50
54
  ```
51
55
 
52
56
  Alternatively, you can use an ask–tell interface with batched AB-MCTS sampling steps:
@@ -56,8 +60,9 @@ import treequest as tq
56
60
 
57
61
  State = str
58
62
 
59
- def generate(parent_state: State | None) -> tuple[State, float]:
60
- ...
63
+
64
+ def generate(parent_state: State | None) -> tuple[State, float]: ...
65
+
61
66
 
62
67
  generate_fns = {"Action A": generate}
63
68
  actions = list(generate_fns.keys())
@@ -124,11 +129,13 @@ import dataclasses
124
129
 
125
130
  import treequest as tq
126
131
 
132
+
127
133
  @dataclasses.dataclass
128
134
  class State:
129
135
  llm_answer: str
130
136
  score: float
131
137
 
138
+
132
139
  def generate(parent_state: State | None) -> tuple[State, float]:
133
140
  """Generate a new node by calling an LLM."""
134
141
  if parent_state is None:
@@ -138,12 +145,14 @@ def generate(parent_state: State | None) -> tuple[State, float]:
138
145
 
139
146
  return state, state.score
140
147
 
148
+
141
149
  def initial_generation() -> State:
142
150
  """
143
151
  Call LLM API to generate an initial answer.
144
152
  """
145
153
  ...
146
154
 
155
+
147
156
  def refine_answer(llm_answer: str, score: float) -> State:
148
157
  """
149
158
  Call LLM API to refine an answer.
@@ -154,11 +163,11 @@ def refine_answer(llm_answer: str, score: float) -> State:
154
163
  algo = tq.ABMCTSM()
155
164
  search_tree = algo.init_tree()
156
165
  for i in range(20):
157
- search_tree = algo.step(search_tree, {'Action Label': generate})
166
+ search_tree = algo.step(search_tree, {"Action Label": generate})
158
167
  # Logging best node during the search.
159
168
  if (i + 1) % 5 == 0:
160
169
  best_interim_state, _ = tq.top_k(search_tree, algo, k=1)[0]
161
- print(f"Iteration {i+1}: Best state so far = {best_interim_state}")
170
+ print(f"Iteration {i + 1}: Best state so far = {best_interim_state}")
162
171
 
163
172
  best_state, _ = tq.top_k(search_tree, algo, k=1)[0]
164
173
  print(f"Best Answer: {best_state.llm_answer}, Best Score: {best_state.score}")
@@ -173,6 +182,7 @@ from functools import partial
173
182
 
174
183
  import treequest as tq
175
184
 
185
+
176
186
  def generate(llm_name: str, parent_state=None):
177
187
  """
178
188
  Call LLM API using litellm, vllm, etc., to generate a new node
@@ -180,9 +190,12 @@ def generate(llm_name: str, parent_state=None):
180
190
  ...
181
191
  return new_state, new_score
182
192
 
193
+
183
194
  llm_names = ["o4-mini", "gemini-2.5-pro"]
184
195
  # Create dict of different actions backed by different LLMs.
185
- generate_fns = {llm_name: partial(generate, llm_name=llm_name) for llm_name in llm_names}
196
+ generate_fns = {
197
+ llm_name: partial(generate, llm_name=llm_name) for llm_name in llm_names
198
+ }
186
199
 
187
200
  algo = tq.StandardMCTS()
188
201
  search_tree = algo.init_tree()
@@ -250,10 +263,12 @@ from pathlib import Path
250
263
  import treequest as tq
251
264
  from PIL import Image
252
265
 
266
+
253
267
  class State:
254
268
  text: str
255
269
  image: Image.Image
256
270
 
271
+
257
272
  def state_formatter_html(state: State) -> str:
258
273
  """Formats the state for HTML visualization."""
259
274
  buffer = BytesIO()
@@ -263,13 +278,15 @@ def state_formatter_html(state: State) -> str:
263
278
  # In case state.text cannot be trusted, we recommend e.g., html.escape(state.text) to avoid html injection.
264
279
  return f'<p>{state.text}</p><br/><img src="data:image/webp;base64,{img_str}" width=100% />'
265
280
 
281
+
266
282
  generate_fns = {
267
283
  "action_1": ... # Define your node generation functions (actions) here
268
284
  }
269
285
 
270
286
  algo = tq.ABMCTSA()
271
287
  search_tree = algo.init_tree()
272
- output_dir = Path("search_tree"); output_dir.mkdir(exist_ok=True)
288
+ output_dir = Path("search_tree")
289
+ output_dir.mkdir(exist_ok=True)
273
290
  for i in range(10):
274
291
  search_tree = algo.step(search_tree, generate_fns)
275
292
  # Rendering "latest.html" for checking search progress on the fly
@@ -278,11 +295,16 @@ for i in range(10):
278
295
  search_tree,
279
296
  output_basename=output_dir / "latest",
280
297
  format="html",
281
- state_formatter=state_formatter_html, # Use html custom formetter
298
+ state_formatter=state_formatter_html, # Use html custom formetter
282
299
  )
283
300
 
284
301
  tq.render(search_tree, output_basename=output_dir / "final", format="pdf")
285
- tq.render(search_tree, output_basename=output_dir / "final", format="html", state_formatter=state_formatter_html)
302
+ tq.render(
303
+ search_tree,
304
+ output_basename=output_dir / "final",
305
+ format="html",
306
+ state_formatter=state_formatter_html,
307
+ )
286
308
  ```
287
309
 
288
310
  > **IMPORTANT:** When using HTML format, ensure that the HTML file is securely handled, especially if the state formatter includes raw HTML content. Avoid opening untrusted HTML files in your browser. For example, XSS (cross site scripting) attacks can occur if the state includes malicious HTML/JavaScript code.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "treequest"
3
- version = "0.3.2"
3
+ version = "0.3.3"
4
4
  description = "A Tree Search Library with Flexible API for LLM Inference-Time Scaling"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -44,16 +44,22 @@ build-backend = "hatchling.build"
44
44
  [dependency-groups]
45
45
  dev = [
46
46
  "line-profiler>=4.2.0",
47
- "mypy>=1.15.0",
47
+ # Pin ruff and mypy so that their new releases do not change CI results.
48
+ # Keep ruff in sync with .pre-commit-config.yaml.
49
+ "mypy==2.4.0",
48
50
  "pre-commit>=4.2.0",
49
51
  "pytest>=8.3.4",
50
52
  "pytest-xdist>=3.6.1",
51
- "ruff>=0.9.9",
53
+ "ruff==0.17.1",
52
54
  "tqdm>=4.64.0",
53
55
  "types-tqdm>=4.64.0",
54
56
  "types-PyYAML>=6.0.0",
55
57
  ]
56
58
 
59
+ [tool.ruff.lint]
60
+ # The rules Ruff enabled by default before 0.16, which expanded its default rule set.
61
+ select = ["E4", "E7", "E9", "F"]
62
+
57
63
  [tool.hatch.build.targets.wheel]
58
64
  packages = ["src/treequest"]
59
65
  include = [
@@ -0,0 +1,58 @@
1
+ import importlib
2
+ from pathlib import Path
3
+
4
+ from treequest.imports import try_import
5
+
6
+ _ARVIZ_IMPORT_ATTEMPTS = 3
7
+
8
+
9
+ def _import_arviz() -> None:
10
+ # TODO: Remove this workaround after arviz fixes the race in its daily warning
11
+ # https://github.com/arviz-devs/arviz/issues/2530
12
+ # arviz 0.23.3 and 0.23.4 update the warning's stamp file through a fixed
13
+ # temporary file, so importing arviz from several processes at once can raise
14
+ # FileNotFoundError. The process that won has already updated the stamp, so
15
+ # importing again normally succeeds.
16
+ for attempt in range(1, _ARVIZ_IMPORT_ATTEMPTS + 1):
17
+ try:
18
+ importlib.import_module("arviz")
19
+ return
20
+ except FileNotFoundError as e:
21
+ # The process that lost the race fails to rename the temporary file.
22
+ lost_race = Path(e.filename or "").name == "daily_warning.tmp"
23
+ if not lost_race or attempt == _ARVIZ_IMPORT_ATTEMPTS:
24
+ raise
25
+ # Leave sys.modules as it is: Python has already dropped the failed
26
+ # package, the leftover arviz.preview is safe to reuse, and another
27
+ # thread may be importing arviz by now.
28
+
29
+
30
+ with try_import() as _import:
31
+ import jax
32
+ from packaging.version import Version
33
+
34
+ # TODO: Remove this hotfix after numpyro fixes incompatibility with jax>=0.7
35
+ # https://github.com/pyro-ppl/numpyro/issues/2051
36
+ if Version(jax.__version__) >= Version("0.7.0"):
37
+ import jax.experimental.pjit as _pjit
38
+ from jax.extend.core.primitives import jit_p
39
+
40
+ _pjit.pjit_p = jit_p # type: ignore
41
+ import numpy as np
42
+ import numpyro # type: ignore
43
+ import pandas as pd # type: ignore
44
+
45
+ _import_arviz() # Import arviz before pymc does; see _import_arviz.
46
+ import pymc as pm # type: ignore
47
+ from pymc.sampling.jax import sample_numpyro_nuts # type: ignore
48
+ from xarray import DataArray
49
+
50
+ __all__ = [
51
+ "jax",
52
+ "np",
53
+ "numpyro",
54
+ "pd",
55
+ "pm",
56
+ "sample_numpyro_nuts",
57
+ "DataArray",
58
+ ]
@@ -1,29 +0,0 @@
1
- from treequest.imports import try_import
2
-
3
- with try_import() as _import:
4
- import jax
5
- from packaging.version import Version
6
-
7
- # TODO: Remove this hotfix after numpyro fixes incompatibility with jax>=0.7
8
- # https://github.com/pyro-ppl/numpyro/issues/2051
9
- if Version(jax.__version__) >= Version("0.7.0"):
10
- import jax.experimental.pjit as _pjit
11
- from jax.extend.core.primitives import jit_p
12
-
13
- _pjit.pjit_p = jit_p # type: ignore
14
- import numpy as np
15
- import numpyro # type: ignore
16
- import pandas as pd # type: ignore
17
- import pymc as pm # type: ignore
18
- from pymc.sampling.jax import sample_numpyro_nuts # type: ignore
19
- from xarray import DataArray
20
-
21
- __all__ = [
22
- "jax",
23
- "np",
24
- "numpyro",
25
- "pd",
26
- "pm",
27
- "sample_numpyro_nuts",
28
- "DataArray",
29
- ]
File without changes
File without changes