Has anyone successfully set up the EMReady or EMReady2 sharpening program on a 50-series GPU? Its default CUDA version 11.8 is incompatible with these GPUs. If so, would you mind sharing all the package versions inside your conda environment (conda list). Thank you!
Thanks for reminding me - I need to investigate this myself.
EMReady2 seems to have had some updates since I last downloaded it. I guess I’ll have a look at the current version.
Tentatively, I’ve got a conda environment with Python 3.14 and CUDA13 PyTorch and all other (updated) dependencies working, but it’s broken the selective_scan_interface.py code so it starts running then falls flat on its face. I’ll update if I make any progress on a fix.
OK, I’ve got it working. I think. I need to test a little more to make sure output is sane across a range of maps. I’ll write up how I got it working and make a pull request on the emready github tomorrow.
have it working as well, (with a working progress bar :P) if you need any help let me know
Hi,you can refer this
I am using RTX5080, and it works.
For me, I upgrade the Nvidia driver, and install the new version of mamba-ssm, causal-conv1d …
Nice to see others jump in. ![]()
Here’s a working Python 3.14 environment (as 3.10 does not have support for much longer):
conda create -n emready2 python=3.14
conda activate emready2
git clone https://github.com/huang-laboratory/EMReady2/
cd EMReady2
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu130
pip install numpy scipy mrcfile biopython einops monai numba llvmlite transformers packaging wheel
pip install causal-conv1d ## takes a long time to build
pip install mamba-ssm --no-build-isolation ##takes even longer to build, NBI needed to find dependencies
pip install -e . --no-deps
git apply update.patch ## fixes selective_scan_interface.py crash
cd model_weights
wget http://huanglab.phys.hust.edu.cn/EMReady2/model_weights/model_1p0.pt
wget http://huanglab.phys.hust.edu.cn/EMReady2/model_weights/model_0p6.pt
cd ..
emready [input] [ouput]
The patch file:
diff --git a/emready/vendor/bimamba_ssm/ops/selective_scan_interface.py b/emready/vendor/bimamba_ssm/ops/selective_scan_interface.py
index 7a0f895..f72601e 100644
--- a/emready/vendor/bimamba_ssm/ops/selective_scan_interface.py
+++ b/emready/vendor/bimamba_ssm/ops/selective_scan_interface.py
@@ -252,8 +252,8 @@ class MambaInnerFnNoOutProj(torch.autograd.Function):
conv1d_weight = rearrange(conv1d_weight, "d 1 w -> d w")
x, z = xz.chunk(2, dim=1)
conv1d_bias = conv1d_bias.contiguous() if conv1d_bias is not None else None
- conv1d_out = causal_conv1d_cuda.causal_conv1d_fwd(
- x, conv1d_weight, conv1d_bias, None, None, None, True
+ conv1d_out = causal_conv1d_fn(
+ x, conv1d_weight, conv1d_bias, activation="silu"
)
# We're being very careful here about the layout, to avoid extra transposes.
# We want delta to have d as the slowest moving dimension
@@ -355,14 +355,14 @@ class MambaInnerFnNoOutProj(torch.autograd.Function):
if dout.stride(-1) != 1:
dout = dout.contiguous()
if ctx.checkpoint_lvl == 1:
- conv1d_out = causal_conv1d_cuda.causal_conv1d_fwd(
- x, conv1d_weight, conv1d_bias, None, None, None, True
+ conv1d_out = causal_conv1d_fn(
+ x, conv1d_weight, conv1d_bias, activation="silu"
)
delta = rearrange(
delta_proj_weight @ x_dbl[:, :delta_rank].t(), "d (b l) -> b d l", l=L
)
# The kernel supports passing in a pre-allocated dz (e.g., in case we want to fuse the
- # backward of selective_scan_cuda with the backward of chunk).
+ # backward of selective_scan_cuda with the backward of chunk.
dxz = torch.empty_like(xz) # (batch, dim, seqlen)
dx, dz = dxz.chunk(2, dim=1)
# dout_y = rearrange(dout, "b l d -> b d l") # because no arrange at end of forward, so dout shape is b d l
@@ -423,17 +423,29 @@ class MambaInnerFnNoOutProj(torch.autograd.Function):
)
# The kernel supports passing in a pre-allocated dx (e.g., in case we want to fuse the
# backward of conv1d with the backward of chunk).
+ # causal_conv1d_bwd signature for v1.6.x: (x, weight, bias, dout, seq_idx, initial_states,
+ # dfinal_states, dx, dinitial_states, activation,
+ # dbias, return_dinitial_states, bool)
+ width = conv1d_weight.shape[-1]
+ initial_states_shape = (x.shape[0], x.shape[1], width - 1)
+ dinitial_states = torch.zeros(initial_states_shape, device=x.device, dtype=x.dtype)
+ if conv1d_bias is not None:
+ dbias = torch.zeros_like(conv1d_bias)
+ else:
+ dbias = None
dx, dconv1d_weight, dconv1d_bias, *_ = causal_conv1d_cuda.causal_conv1d_bwd(
x,
conv1d_weight,
conv1d_bias,
dconv1d_out,
None,
- None,
- None,
+ None, # initial_states (not used in mamba_inner_fn pattern)
+ None, # dfinal_states
dx,
- False,
- True,
+ dinitial_states,
+ None, # activation
+ dbias,
+ False, # return_dinitial_states
)
dconv1d_bias = dconv1d_bias if conv1d_bias is not None else None
dconv1d_weight = rearrange(dconv1d_weight, "d w -> d 1 w")
@@ -481,8 +493,8 @@ class MambaInnerFn(torch.autograd.Function):
xz: (batch, dim, seqlen)
"""
assert (
- causal_conv1d_cuda is not None
- ), "causal_conv1d_cuda is not available. Please install causal-conv1d."
+ causal_conv1d_fn is not None
+ ), "causal_conv1d_fn is not available. Please install causal-conv1d."
assert checkpoint_lvl in [0, 1]
L = xz.shape[-1]
delta_rank = delta_proj_weight.shape[1]
@@ -503,8 +515,8 @@ class MambaInnerFn(torch.autograd.Function):
conv1d_weight = rearrange(conv1d_weight, "d 1 w -> d w")
x, z = xz.chunk(2, dim=1)
conv1d_bias = conv1d_bias.contiguous() if conv1d_bias is not None else None
- conv1d_out = causal_conv1d_cuda.causal_conv1d_fwd(
- x, conv1d_weight, conv1d_bias, None, None, None, True
+ conv1d_out = causal_conv1d_fn(
+ x, conv1d_weight, conv1d_bias, activation="silu"
)
# We're being very careful here about the layout, to avoid extra transposes.
# We want delta to have d as the slowest moving dimension
@@ -586,8 +598,8 @@ class MambaInnerFn(torch.autograd.Function):
def backward(ctx, dout):
# dout: (batch, seqlen, dim)
assert (
- causal_conv1d_cuda is not None
- ), "causal_conv1d_cuda is not available. Please install causal-conv1d."
+ causal_conv1d_fn is not None
+ ), "causal_conv1d_fn is not available. Please install causal-conv1d."
(
xz,
conv1d_weight,
@@ -613,14 +625,14 @@ class MambaInnerFn(torch.autograd.Function):
if dout.stride(-1) != 1:
dout = dout.contiguous()
if ctx.checkpoint_lvl == 1:
- conv1d_out = causal_conv1d_cuda.causal_conv1d_fwd(
- x, conv1d_weight, conv1d_bias, None, None, None, True
+ conv1d_out = causal_conv1d_fn(
+ x, conv1d_weight, conv1d_bias, activation="silu"
)
delta = rearrange(
delta_proj_weight @ x_dbl[:, :delta_rank].t(), "d (b l) -> b d l", l=L
)
# The kernel supports passing in a pre-allocated dz (e.g., in case we want to fuse the
- # backward of selective_scan_cuda with the backward of chunk).
+ # backward of selective_scan_cuda with the backward of chunk.
dxz = torch.empty_like(xz) # (batch, dim, seqlen)
dx, dz = dxz.chunk(2, dim=1)
dout = rearrange(dout, "b l e -> e (b l)")
@@ -686,17 +698,29 @@ class MambaInnerFn(torch.autograd.Function):
)
# The kernel supports passing in a pre-allocated dx (e.g., in case we want to fuse the
# backward of conv1d with the backward of chunk).
+ # causal_conv1d_bwd signature for v1.6.x: (x, weight, bias, dout, seq_idx, initial_states,
+ # dfinal_states, dx, dinitial_states, activation,
+ # dbias, return_dinitial_states, bool)
+ width = conv1d_weight.shape[-1]
+ initial_states_shape = (x.shape[0], x.shape[1], width - 1)
+ dinitial_states = torch.zeros(initial_states_shape, device=x.device, dtype=x.dtype)
+ if conv1d_bias is not None:
+ dbias = torch.zeros_like(conv1d_bias)
+ else:
+ dbias = None
dx, dconv1d_weight, dconv1d_bias, *_ = causal_conv1d_cuda.causal_conv1d_bwd(
x,
conv1d_weight,
conv1d_bias,
dconv1d_out,
None,
- None,
- None,
+ None, # initial_states (not used in mamba_inner_fn pattern)
+ None, # dfinal_states
dx,
- False,
- True,
+ dinitial_states,
+ None, # activation
+ dbias,
+ False, # return_dinitial_states
)
dconv1d_bias = dconv1d_bias if conv1d_bias is not None else None
dconv1d_weight = rearrange(dconv1d_weight, "d w -> d 1 w")
@@ -746,6 +770,9 @@ class BiMambaInnerFn(torch.autograd.Function):
"""
xz: (batch, dim, seqlen)
"""
+ assert (
+ causal_conv1d_fn is not None
+ ), "causal_conv1d_fn is not available. Please install causal-conv1d."
assert checkpoint_lvl in [0, 1]
L = xz.shape[-1]
delta_rank = delta_proj_weight.shape[1]
@@ -766,8 +793,8 @@ class BiMambaInnerFn(torch.autograd.Function):
conv1d_weight = rearrange(conv1d_weight, "d 1 w -> d w")
x, z = xz.chunk(2, dim=1)
conv1d_bias = conv1d_bias.contiguous() if conv1d_bias is not None else None
- conv1d_out = causal_conv1d_cuda.causal_conv1d_fwd(
- x, conv1d_weight, conv1d_bias, None, None, None, True
+ conv1d_out = causal_conv1d_fn(
+ x, conv1d_weight, conv1d_bias, activation="silu"
)
# We're being very careful here about the layout, to avoid extra transposes.
# We want delta to have d as the slowest moving dimension
@@ -894,14 +921,14 @@ class BiMambaInnerFn(torch.autograd.Function):
if dout.stride(-1) != 1:
dout = dout.contiguous()
if ctx.checkpoint_lvl == 1:
- conv1d_out = causal_conv1d_cuda.causal_conv1d_fwd(
- x, conv1d_weight, conv1d_bias, None, None, None, True
+ conv1d_out = causal_conv1d_fn(
+ x, conv1d_weight, conv1d_bias, activation="silu"
)
delta = rearrange(
delta_proj_weight @ x_dbl[:, :delta_rank].t(), "d (b l) -> b d l", l=L
)
# The kernel supports passing in a pre-allocated dz (e.g., in case we want to fuse the
- # backward of selective_scan_cuda with the backward of chunk).
+ # backward of selective_scan_cuda with the backward of chunk.
dxz = torch.empty_like(xz) # (batch, dim, seqlen)
dx, dz = dxz.chunk(2, dim=1)
dout = rearrange(dout, "b l e -> e (b l)")
@@ -1005,17 +1032,29 @@ class BiMambaInnerFn(torch.autograd.Function):
)
# The kernel supports passing in a pre-allocated dx (e.g., in case we want to fuse the
# backward of conv1d with the backward of chunk).
+ # causal_conv1d_bwd signature for v1.6.x: (x, weight, bias, dout, seq_idx, initial_states,
+ # dfinal_states, dx, dinitial_states, activation,
+ # dbias, return_dinitial_states, bool)
+ width = conv1d_weight.shape[-1]
+ initial_states_shape = (x.shape[0], x.shape[1], width - 1)
+ dinitial_states = torch.zeros(initial_states_shape, device=x.device, dtype=x.dtype)
+ if conv1d_bias is not None:
+ dbias = torch.zeros_like(conv1d_bias)
+ else:
+ dbias = None
dx, dconv1d_weight, dconv1d_bias, *_ = causal_conv1d_cuda.causal_conv1d_bwd(
x,
conv1d_weight,
conv1d_bias,
dconv1d_out,
None,
- None,
- None,
+ None, # initial_states (not used in mamba_inner_fn pattern)
+ None, # dfinal_states
dx,
- False,
- True,
+ dinitial_states,
+ None, # activation
+ dbias,
+ False, # return_dinitial_states
)
dconv1d_bias = dconv1d_bias if conv1d_bias is not None else None
dconv1d_weight = rearrange(dconv1d_weight, "d w -> d 1 w")
The selective_scan fix was me experimenting with opencode/Qwen3-coder-next, but output maps look almost identical to earlier EMReady2 implementation runs.
Conda env:
name: EMReady2
channels:
- conda-forge
dependencies:
- _openmp_mutex=4.5=20_gnu
- bzip2=1.0.8=hda65f42_9
- ca-certificates=2026.5.20=hbd8a1cb_0
- ld_impl_linux-64=2.45.1=default_hbd61a6d_102
- libexpat=2.8.1=hecca717_0
- libffi=3.5.2=h3435931_0
- libgcc=15.2.0=he0feb66_19
- libgomp=15.2.0=he0feb66_19
- liblzma=5.8.3=hb03c661_0
- libmpdec=4.0.0=hb03c661_1
- libsqlite=3.53.1=h0c1763c_0
- libuuid=2.42.1=h5347b49_0
- libzlib=1.3.2=h25fd6f3_2
- ncurses=6.6=hdb14827_0
- openssl=3.6.2=h35e630c_0
- pip=26.1.2=pyh145f28c_0
- python=3.14.5=habeac84_100_cp314
- python_abi=3.14=8_cp314
- readline=8.3=h853b02a_0
- tk=8.6.13=noxft_h366c992_103
- tzdata=2025c=hc9c84f9_1
- zstd=1.5.7=hb78ec9c_6
- pip:
- annotated-doc==0.0.4
- anyio==4.13.0
- apache-tvm-ffi==0.1.9
- biopython==1.87
- causal-conv1d==1.6.2.post1
- certifi==2026.5.20
- click==8.4.1
- cloudpickle==3.1.2
- cuda-bindings==13.3.1
- cuda-core==1.0.1
- cuda-pathfinder==1.5.5
- cuda-python==13.3.1
- cuda-toolkit==13.0.2
- einops==0.8.2
- emready==0.1.0
- filelock==3.29.0
- fsspec==2026.4.0
- h11==0.16.0
- hf-xet==1.5.0
- httpcore==1.0.9
- httpx==0.28.1
- huggingface-hub==1.17.0
- idna==3.18
- jinja2==3.1.6
- llvmlite==0.47.0
- mamba-ssm==2.3.2.post1
- markdown-it-py==4.2.0
- markupsafe==3.0.3
- mdurl==0.1.2
- ml-dtypes==0.5.4
- monai==1.5.2
- mpmath==1.3.0
- mrcfile==1.5.4
- networkx==3.6.1
- ninja==1.13.0
- numba==0.65.1
- numpy==2.4.4
- nvidia-cublas==13.1.1.3
- nvidia-cuda-cupti==13.0.85
- nvidia-cuda-nvrtc==13.0.88
- nvidia-cuda-runtime==13.0.96
- nvidia-cudnn-cu13==9.20.0.48
- nvidia-cufft==12.0.0.61
- nvidia-cufile==1.15.1.6
- nvidia-curand==10.4.0.35
- nvidia-cusolver==12.0.4.66
- nvidia-cusparse==12.6.3.3
- nvidia-cusparselt-cu13==0.8.1
- nvidia-cutlass-dsl==4.5.2
- nvidia-cutlass-dsl-libs-base==4.5.2
- nvidia-nccl-cu13==2.29.7
- nvidia-nvjitlink==13.0.88
- nvidia-nvshmem-cu13==3.4.5
- nvidia-nvtx==13.0.85
- packaging==26.2
- pillow==12.2.0
- psutil==7.2.2
- pygments==2.20.0
- pyyaml==6.0.3
- quack-kernels==0.5.0
- regex==2026.5.9
- rich==15.0.0
- safetensors==0.7.0
- scipy==1.17.1
- setuptools==70.2.0
- shellingham==1.5.4
- sympy==1.14.0
- tilelang==0.1.8
- tokenizers==0.22.2
- torch==2.12.0+cu130
- torch-c-dlpack-ext==0.1.5
- torchaudio==2.11.0+cu130
- torchvision==0.27.0+cu130
- tqdm==4.67.3
- transformers==5.9.0
- triton==3.7.0
- typer==0.25.1
- typing-extensions==4.15.0
- wheel==0.47.0
- z3-solver==4.15.4.0
prefix: /home/rbs-sci/.anaconda/EMReady2