I believe the backward pass for torch.sign() returns all gradients simply as zeros and not the output expected from a straight through estimator.
Here is the code and outputs to reproduce this:
import torch
import torch.nn as nn
from torch.autograd import Variable, Function
 
class BinaryLayer(nn.Module):
    def forward(self, input):
        return torch.sign(input)
 
input = torch.randn(4,4)
input = Variable(input, requires_grad=True)
 
model = BinaryLayer()
output = model(input)
loss = output.mean()
 
>>> loss.backward()
>>> input
Variable containing:
-1.4272  1.5698  2.6661  0.4438
 0.4978  0.8987  1.6969  0.2067
 0.3880 -2.1434 -1.1588 -0.5567
-1.2435 -0.1010  0.7215 -0.9209
[torch.FloatTensor of size 4x4]
 
>>> input.grad
Variable containing:
 0  0  0  0
 0  0  0  0
 0  0  0  0
 0  0  0  0
[torch.FloatTensor of size 4x4]

Hence, I implemented this layer. It works when used in isolation. Here is a snippet to verify it:
class BinaryLayer(Function):
    def forward(self, input):
        return torch.sign(input)
 
    def backward(self, grad_output):
        return grad_output.clamp_(-1, 1)
 
input = torch.randn(4,4)
input = Variable(input, requires_grad=True)
 
model = BinaryLayer()
output = model(input)
loss = output.mean()
>>> loss.backward()
>>> input
Variable containing:
 0.1690 -0.0028  1.4472 -0.1484
-0.6580  0.9200  0.5465  0.3896
-2.1211 -1.4266 -0.9634 -1.3991
-1.4426  1.4950  0.9849  0.4504
[torch.FloatTensor of size 4x4]
 
>>> input.grad
Variable containing:
1.00000e-02 *
  6.2500  6.2500  6.2500  6.2500
  6.2500  6.2500  6.2500  6.2500
  6.2500  6.2500  6.2500  6.2500
  6.2500  6.2500  6.2500  6.2500
[torch.FloatTensor of size 4x4]

However, I am unable to integrate this into a model. How do I go about this?