internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: bentoml/BentoML

Issue:
bug: unintended creation of wheel directory
### Describe the bug

When the user specifies Python options with `wheels` as empty list instead of `None`, bentoml will create the wheel directory, causing `install.sh` to fail because it tries to install `*.whl` from the wheels directory, but there are no wheel files inside. 

This is normally not an issue because the user is expected to create a `bentofile.yaml` and use the bentoml CLI to build their bentos (and the user will typically not specify the wheels section at all if there are none), but in specific workflows where it is more convenient to use the bentoml Python interface to build bentos (e.g. when the user is using a notebook-centric environment like Databricks), the user may specify an empty list for wheels instead of `None`.

It is fairly simple to workaround this (we can specify `None` instead of empty list when calling `bentoml.bentos.build()`), but it would be nice if it could work with empty list as well. I can work on this, just let me know if it's ok to proceed.

```python
if self.wheels is not None:
    bento_fs.makedirs(wheels_folder, recreate=True)
    for whl_file in self.wheels:  # pylint: disable=not-an-iterable
        whl_file = resolve_user_filepath(whl_file, build_ctx)
        copy_file_to_fs_folder(whl_file, bento_fs, wheels_folder)
```

```bash
if [ -d "$WHEELS_DIR" ]; then
    echo "Installing wheels packaged in Bento.."
    pip3 install "$WHEELS_DIR"/*.whl "${PIP_ARGS[@]}"
fi
```

I believe the check should be simplified to `if self.wheels`, so it covers the case of empty list as well.



### To reproduce

_No response_

### Expected behavior

_No response_

### Environment

bentoml: 1.0.8 onwards
Python: 3.8



Discussion:
I think this can be fixed by simply change
```python
if self.wheels is not None: ...
```
to 
```python
if self.wheels: ...
```
should cover your case.

The reason for checking `is not None` is that we want to avoid type coercion in Python. But I guess it is a thing in Python

Resolving patch:
diff --git a/src/bentoml/_internal/bento/build_config.py b/src/bentoml/_internal/bento/build_config.py
--- a/src/bentoml/_internal/bento/build_config.py
+++ b/src/bentoml/_internal/bento/build_config.py
@@ -514,7 +514,7 @@ def write_to_bento(self, bento_fs: FS, build_ctx: str) -> None:
         build_bentoml_editable_wheel(bento_fs.getsyspath(wheels_folder))
 
         # Move over required wheel files
-        if self.wheels is not None:
+        if self.wheels:
             bento_fs.makedirs(wheels_folder, recreate=True)
             for whl_file in self.wheels:  # pylint: disable=not-an-iterable
                 whl_file = resolve_user_filepath(whl_file, build_ctx)


Test patch:
Repository: bentoml/BentoML

Issue:
chore: passing `--resolver=backtracking` to pip-compile
### Feature request

When locking requirements.txt for `bentoml build`, BentoML are utilizing `pip-tools`.

For this we need to pass in the `--resolver` args to pip-compile in `PythonOptions.write_to_bento` to address the following warning:

```prolog
WARNING: the legacy dependency resolver is deprecated and will be removed in future versions of pip-tools. The default resolver will be changed to 'backtracking' in pip-tools 7.0.0. Specify --resolver=backtracking to silence this warning.
```

### Motivation

_No response_

### Other

_No response_


Discussion:
took the chore and did it, so could you assign it to me please :))

Resolving patch:
diff --git a/src/bentoml/_internal/bento/build_config.py b/src/bentoml/_internal/bento/build_config.py
--- a/src/bentoml/_internal/bento/build_config.py
+++ b/src/bentoml/_internal/bento/build_config.py
@@ -652,6 +652,7 @@ def write_to_bento(self, bento_fs: FS, build_ctx: str) -> None:
                     "--allow-unsafe",
                     "--no-header",
                     f"--output-file={pip_compile_out}",
+                    "--resolver=backtracking",
                 ]
             )
             logger.info("Locking PyPI package versions.")


Test patch:
Repository: bentoml/BentoML

Issue:
feature: `client.health`
### Feature request

client to have a health function:
```python
client.health()
await client.async_health()
```

### Motivation

For HTTP, would probably just need to invoke `/readyz`, and for gRPC is to invoke the `Health` rpc from `grpc.health.v1.HealthServicer`.

### Other

_No response_


Discussion:
@aarnphm Hi! I'm a newbie to BentoML. May I work on this issue?
Hi there, feel free to pick up this issue after https://github.com/bentoml/BentoML/pull/3280 is merged.
Has anyone started this one? It's being here for a while
feel free to pick it up. The client.health is already implemented for gRPC client. You can go a head and implement for HTTP client.

Resolving patch:
diff --git a/src/bentoml/_internal/client/http.py b/src/bentoml/_internal/client/http.py
--- a/src/bentoml/_internal/client/http.py
+++ b/src/bentoml/_internal/client/http.py
@@ -4,6 +4,7 @@
 import time
 import socket
 import typing as t
+import asyncio
 import logging
 import urllib.error
 import urllib.request
@@ -77,6 +78,14 @@ def wait_until_server_ready(
             logger.error(err)
             raise
 
+    async def async_health(self) -> t.Any:
+        async with aiohttp.ClientSession(self.server_url) as sess:
+            async with sess.get("/readyz") as resp:
+                return resp
+
+    def health(self) -> t.Any:
+        return asyncio.run(self.async_health())
+
     @classmethod
     def from_url(cls, server_url: str, **kwargs: t.Any) -> HTTPClient:
         server_url = server_url if "://" in server_url else "http://" + server_url


Test patch:
diff --git a/tests/e2e/bento_server_http/tests/test_client.py b/tests/e2e/bento_server_http/tests/test_client.py
new file mode 100644
--- /dev/null
+++ b/tests/e2e/bento_server_http/tests/test_client.py
@@ -0,0 +1,24 @@
+import pytest
+
+import bentoml
+from bentoml.client import HTTPClient
+
+
+@pytest.fixture(scope="session")
+def http_client(host: str) -> HTTPClient:
+    service = bentoml.load(bento_identifier="service:svc")
+
+    return HTTPClient(service, f"http://{host}")
+
+
+@pytest.mark.asyncio
+async def test_async_health(http_client: HTTPClient) -> None:
+    resp = await http_client.async_health()
+
+    assert resp.status == 200
+
+
+def test_health(http_client: HTTPClient) -> None:
+    resp = http_client.health()
+
+    assert resp.status == 200
Repository: bentoml/BentoML

Issue:
bugs: Exception during shutdown
Issuing SIGTERM (Ctrl+C) to a runner server causes the following exception to be raised. 

```
023-05-01T23:27:09-0700 [ERROR] [cli] Exception in callback <bound method Arbiter.manage_watchers of <circus.arbiter.Arbiter object at 0x10719e2c0>>
Traceback (most recent call last):
  File "/opt/miniconda3/envs/bentoml/lib/python3.10/site-packages/tornado/ioloop.py", line 921, in _run
    val = self.callback()
  File "/opt/miniconda3/envs/bentoml/lib/python3.10/site-packages/circus/util.py", line 1038, in wrapper
    raise ConflictError("arbiter is already running %s command"
circus.exc.ConflictError: arbiter is already running arbiter_stop command
```


Discussion:

Resolving patch:
diff --git a/src/bentoml/_internal/marshal/dispatcher.py b/src/bentoml/_internal/marshal/dispatcher.py
--- a/src/bentoml/_internal/marshal/dispatcher.py
+++ b/src/bentoml/_internal/marshal/dispatcher.py
@@ -235,7 +235,7 @@ async def train_optimizer(
                     info.enqueue_time = now
                 self._loop.create_task(self.outbound_call(inputs_info))
         except asyncio.CancelledError:
-            return
+            raise
         except Exception as e:  # pylint: disable=broad-except
             logger.error(traceback.format_exc(), exc_info=e)
 
@@ -313,7 +313,7 @@ async def controller(self):
                 inputs_info = tuple(self._queue.pop() for _ in range(n_call_out))
                 self._loop.create_task(self.outbound_call(inputs_info))
             except asyncio.CancelledError:
-                return
+                raise
             except Exception as e:  # pylint: disable=broad-except
                 logger.error(traceback.format_exc(), exc_info=e)
 


Test patch:
diff --git a/tests/e2e/bento_server_http/tests/test_serve.py b/tests/e2e/bento_server_http/tests/test_serve.py
--- a/tests/e2e/bento_server_http/tests/test_serve.py
+++ b/tests/e2e/bento_server_http/tests/test_serve.py
@@ -20,7 +20,7 @@ def test_http_server(bentoml_home: str):
 
     server.stop()
 
-    timeout = 60
+    timeout = 10
     start_time = time.time()
     while time.time() - start_time < timeout:
         retcode = server.process.poll()
@@ -48,7 +48,7 @@ def test_http_server_ctx(bentoml_home: str):
 
         assert res == {"more_test": "and more json"}
 
-    timeout = 60
+    timeout = 10
     start_time = time.time()
     while time.time() - start_time < timeout:
         retcode = server.process.poll()
Repository: bentoml/BentoML

Issue:
bug: Issue with "bentoml build" command failing when Python path contains special character "@" in the current project
### Describe the bug

I encountered an issue while using the "bentoml build" command in my current project. The command fails when the Python path being used contains a special character "@".

### To reproduce

1. Prepare a Python venv that contains `@` in the path
2. install bentoml
3. run bentoml build

### Expected behavior

_No response_

### Environment

All versions.


Discussion:
dup: https://github.com/bentoml/BentoML/issues/3489

Resolving patch:
diff --git a/src/bentoml/_internal/bento/bento.py b/src/bentoml/_internal/bento/bento.py
--- a/src/bentoml/_internal/bento/bento.py
+++ b/src/bentoml/_internal/bento/bento.py
@@ -26,6 +26,7 @@
 from ..store import StoreItem
 from ..types import PathType
 from ..utils import bentoml_cattr
+from ..utils import encode_path_for_uri
 from ..utils import copy_file_to_fs_folder
 from ..utils import normalize_labels_value
 from ..models import ModelStore, copy_model
@@ -197,7 +198,7 @@ def create(
         )
 
         bento_fs = fs.open_fs(f"temp://bentoml_bento_{bento_name}")
-        ctx_fs = fs.open_fs(build_ctx)
+        ctx_fs = fs.open_fs(encode_path_for_uri(build_ctx))
 
         models: t.Set[Model] = set()
         resolved_aliases: t.Dict[Tag, str] = {}
diff --git a/src/bentoml/_internal/utils/__init__.py b/src/bentoml/_internal/utils/__init__.py
--- a/src/bentoml/_internal/utils/__init__.py
+++ b/src/bentoml/_internal/utils/__init__.py
@@ -27,6 +27,7 @@
 from ..types import LazyType
 from .cattr import bentoml_cattr
 from .lazy_loader import LazyLoader
+from .uri import encode_path_for_uri
 
 if TYPE_CHECKING:
     from fs.base import FS
@@ -265,7 +266,7 @@ def copy_file_to_fs_folder(
     """
     src_path = os.path.realpath(os.path.expanduser(src_path))
     dir_name, file_name = os.path.split(src_path)
-    src_fs = fs.open_fs(dir_name)
+    src_fs = fs.open_fs(encode_path_for_uri(dir_name))
     dst_filename = file_name if dst_filename is None else dst_filename
     dst_path = fs.path.join(dst_folder_path, dst_filename)
     dst_fs.makedir(dst_folder_path, recreate=True)
diff --git a/src/bentoml/_internal/utils/uri.py b/src/bentoml/_internal/utils/uri.py
--- a/src/bentoml/_internal/utils/uri.py
+++ b/src/bentoml/_internal/utils/uri.py
@@ -1,5 +1,6 @@
 import os
 import pathlib
+from urllib.parse import quote
 from urllib.parse import unquote
 from urllib.parse import urlparse
 from urllib.request import url2pathname
@@ -40,3 +41,8 @@ def uri_to_path(uri: str) -> str:
         raise ValueError("Unsupported URI scheme")
     host = "{0}{0}{mnt}{0}".format(os.path.sep, mnt=parsed.netloc)
     return os.path.normpath(os.path.join(host, url2pathname(unquote(parsed.path))))
+
+
+def encode_path_for_uri(path: str) -> str:
+    """Percent-encode non-URL characters in a path."""
+    return quote(path.replace(os.sep, "/"))


Test patch:
Repository: bentoml/BentoML

Issue:
fix(scheduling): expose Strategy class



Discussion:
Hmm can you run `pre-commit run --all-files` again? I thought we set our import lines to be single lines 🤔 
@aarnphm Tried. Nothing changes.
I've upgraded black to the newest version.
hmm this is weird
cc @bojiang please update this with the merge conflict.

Resolving patch:
diff --git a/src/bentoml/__init__.py b/src/bentoml/__init__.py
--- a/src/bentoml/__init__.py
+++ b/src/bentoml/__init__.py
@@ -30,8 +30,10 @@
 from ._internal.context import ServiceContext as Context
 from ._internal.models import Model
 from ._internal.monitoring import monitor
+from ._internal.resource import Resource
 from ._internal.runner import Runnable
 from ._internal.runner import Runner
+from ._internal.runner.strategy import Strategy
 from ._internal.service import Service
 from ._internal.service.loader import load
 from ._internal.tag import Tag
@@ -219,4 +221,6 @@
     "load_config",
     "save_config",
     "set_serialization_strategy",
+    "Strategy",
+    "Resource",
 ]


Test patch:
Repository: bentoml/BentoML

Issue:
bug: bentoml.build API does not work on Windows 10 due to Invalid Tag Exception
### Describe the bug

I try to build my bento with
`bentoml.bentos.build_bentofile(bentofile="bentofile.yaml", build_ctx="src")`
However, when I name my service p05_s1_anomaly_service the following way
`svc = bentoml.Service("p05_s1_anomaly_service", runners=runner_list)`
 I get an error:
```
raise ValueError(
is not a valid BentoML tag: a tag's name or version must consist of alphanumeric characters, '_', '-', or '.', and must start and end with an alphanumeric character
[...]
bentoml.exceptions.BentoMLException: Invalid Tag p05_s1_anomaly_service:jjbpl3f4dc3pafc2
```

I am currently working on Windows, the error is that in the `_parse_tag_from_outputs` method in _bentos.py_, the decoded utf-8 string somehow contains a invalid character for windows user with the API. Fun Fact: The CLI operation does work!

### To reproduce

```
import bentoml

#assuming runner list does exist
svc = bentoml.Service("p05_s1_anomaly_service", runners=runner_list)
```

### Expected behavior

Expect to build the bento, just as with the CLI.

### Environment

bentoml, version 1.1.11  
Python 3.10.13  
platform: windows


Discussion:

Resolving patch:
diff --git a/src/bentoml/bentos.py b/src/bentoml/bentos.py
--- a/src/bentoml/bentos.py
+++ b/src/bentoml/bentos.py
@@ -402,7 +402,7 @@ def _parse_tag_from_outputs(output: bytes) -> str:
         raise BentoMLException(
             f"Failed to find tag from output: {output}\nNote: Output from 'bentoml build' might not be correct. Please open an issue on GitHub."
         )
-    return matched.group(1)
+    return matched.group(1).strip()
 
 
 @inject


Test patch:
Repository: bentoml/BentoML

Issue:
feature: Allow removal of server header
### Feature request

Currently the server header is being exposed with the value 'uvicorn'. This does not pose an immediate security threat. However it exposes implementation details that could potentially aid bad actors in targeting specific software. Minimizing such disclosures is advisable to reduce the risk of targeted attacks.

Uvicorn has an option to disable sending server headers. Ref: https://www.uvicorn.org/settings/#http

### Motivation

We are trying to get some models deployed to production and this is is one of the security blockers.

### Other

I am working on a possible fix that would be unbreaking and backwards compatible.


Discussion:

Resolving patch:
diff --git a/src/_bentoml_impl/worker/service.py b/src/_bentoml_impl/worker/service.py
--- a/src/_bentoml_impl/worker/service.py
+++ b/src/_bentoml_impl/worker/service.py
@@ -192,6 +192,7 @@ def main(
         ssl_keyfile=ssl_keyfile,
         ssl_keyfile_password=ssl_keyfile_password,
         ssl_ca_certs=ssl_ca_certs,
+        server_header=False,
         **uvicorn_extra_options,
     )
 


Test patch:
Repository: bentoml/BentoML

Issue:
bug: module 'socket' has no attribute 'AF_UNIX'
### Describe the bug

Hello,
I'm trying to use Bentoml by playing with the quick start examples. When running the Iris classification example on a windows machine, I have this error message:
```
File "C:\Users\Path\lib\site-packages\uvicorn\server.py", line 140, in startup
    sock = socket.fromfd(config.fd, socket.AF_UNIX, socket.SOCK_STREAM)
AttributeError: module 'socket' has no attribute 'AF_UNIX'
```

I tried to change the socket attribute to AF_INET, the error messages disappear but the client cannot connect to the bentoml server.

Thanks,


### To reproduce

_No response_

### Expected behavior

_No response_

### Environment

bentoml:1.2.12
python:3.9.18
uvicorn:0.29.0
Windows: 11 Pro 22H2


Discussion:

Resolving patch:
diff --git a/src/_bentoml_impl/worker/service.py b/src/_bentoml_impl/worker/service.py
--- a/src/_bentoml_impl/worker/service.py
+++ b/src/_bentoml_impl/worker/service.py
@@ -117,6 +117,8 @@ def main(
     """
     Start a HTTP server worker for given service.
     """
+    import socket
+
     import psutil
     import uvicorn
 
@@ -182,9 +184,8 @@ def main(
 
         asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())  # type: ignore
 
-    uvicorn.run(
+    config = uvicorn.Config(
         app=asgi_app,
-        fd=fd,
         backlog=backlog,
         log_config=None,
         workers=1,
@@ -195,6 +196,8 @@ def main(
         server_header=False,
         **uvicorn_extra_options,
     )
+    socket = socket.socket(fileno=fd)
+    uvicorn.Server(config).run(sockets=[socket])
 
 
 if __name__ == "__main__":


Test patch:
Repository: nerfstudio-project/nerfstudio

Issue:
output accumulation value is very negative
After training for a long time ~81,990 steps on instant ngp, get the following stack trace:

![Screenshot from 2022-07-12 10-56-19](https://user-images.githubusercontent.com/14854811/178564226-68c72f1d-1ebf-4fa6-ba0e-9942a161aed0.png)



Discussion:
Hmm this is after #104 was merged right? ~~I was still getting NaNs, but never this early (maybe at 140k~200k steps).~~ (edit: I ran the train script several times in parallel; one of the runs did produce a NaN in the RGB MLP at around 90k steps)

As an FYI, `-9223372036854775808` is what we get from:
```
>>> torch.tensor(torch.nan).long()
tensor(-9223372036854775808)
```

Resolving patch:
diff --git a/pyrad/fields/instant_ngp_field.py b/pyrad/fields/instant_ngp_field.py
--- a/pyrad/fields/instant_ngp_field.py
+++ b/pyrad/fields/instant_ngp_field.py
@@ -101,7 +101,7 @@ def __init__(
             network_config={
                 "otype": "FullyFusedMLP",
                 "activation": "ReLU",
-                "output_activation": "None",
+                "output_activation": "Sigmoid",
                 "n_neurons": hidden_dim_color,
                 "n_hidden_layers": num_layers_color - 1,
             },
@@ -131,8 +131,8 @@ def get_outputs(self, ray_samples: RaySamples, density_embedding=None):
         dtype = directions_flat.dtype
         d = self.direction_encoding(directions_flat)
         h = torch.cat([d, density_embedding.view(-1, self.geo_feat_dim)], dim=-1)
-        h = self.mlp_head(h).view(*ray_samples.frustums.directions.shape[:-1], -1).to(dtype)
-        rgb = torch.sigmoid(h)
+        rgb = self.mlp_head(h).view(*ray_samples.frustums.directions.shape[:-1], -1).to(dtype)
+        assert rgb.dtype is torch.float32
         return {FieldHeadNames.RGB: rgb}
 
 


Test patch:
Repository: nerfstudio-project/nerfstudio

Issue:
Report "Rays Per Sec" in easier to read format.
It would be great to report the "Rays Per Sec" to fewer sig figs. Ie "1343535.4324" -> "1.34 mil" or "1.34 M". It is becoming trickier to quickly read these numbers now that the model is getting quicker.

Also maybe "Rays Per Sec" -> "Rays / Sec"


Discussion:

Resolving patch:
diff --git a/pyrad/utils/misc.py b/pyrad/utils/misc.py
--- a/pyrad/utils/misc.py
+++ b/pyrad/utils/misc.py
@@ -21,6 +21,7 @@
 from pydoc import locate
 from typing import Any, Dict
 
+from math import floor, log
 import torch
 from omegaconf import DictConfig
 
@@ -90,3 +91,11 @@ def get_hash_str_from_dict(dictionary: Dict[str, Any]) -> str:
     encoded = json.dumps(dictionary, sort_keys=True).encode()
     dhash.update(encoded)
     return dhash.hexdigest()
+
+
+def human_format(num):
+    """Format a number in a more human readable way"""
+    units = ["", "K", "M", "B", "T", "P"]
+    k = 1000.0
+    magnitude = int(floor(log(num, k)))
+    return f"{(num / k**magnitude):.2f} {units[magnitude]}"
diff --git a/scripts/run_eval.py b/scripts/run_eval.py
--- a/scripts/run_eval.py
+++ b/scripts/run_eval.py
@@ -15,6 +15,7 @@
 from pyrad.cameras.camera_paths import CameraPath, get_interpolated_camera_path, get_spiral_path
 from pyrad.data.dataloader import EvalDataloader, setup_dataset_eval, setup_dataset_train
 from pyrad.graphs.base import Graph, setup_graph
+from pyrad.utils.misc import human_format
 from pyrad.utils.writer import TimeWriter
 
 
@@ -200,7 +201,7 @@ def main(
         avg_rays_per_sec = stats_dict["avg rays per sec"]
         avg_fps = stats_dict["avg fps"]
         print(f"Avg. PSNR: {avg_psnr:0.4f}")
-        print(f"Avg. Rays per sec: {avg_rays_per_sec:0.4f}")
+        print(f"Avg. Rays / Sec: {human_format(avg_rays_per_sec)}")
         print(f"Avg. FPS: {avg_fps:0.4f}")
     elif method == MethodType.TRAJ:
         # TODO(ethan): pass in camera information into argparse parser


Test patch: