Repository: pytorch
Issue: Reduce duplication in number of places where we specify dependency pin
Labels: module: ci,triaged,module: devx

### 🐛 Describe the bug

Grepping for expecttest (as an example) we see

```
.ci/docker/requirements-ci.txt:expecttest==0.1.6
.github/requirements/conda-env-macOS-ARM64:# have updated expecttest, but you don't /need/ the updated version
.github/requirements/conda-env-macOS-ARM64:expecttest=0.1.3
.github/requirements/pip-requirements-macOS.txt:expecttest==0.1.6
.github/workflows/lint.yml:          pip install pytest-rerunfailures==11.1.* pytest-flakefinder==1.1.* pytest-xdist==3.3.* expecttest==0.1.* numpy==1.24.*
.lintrunner.toml:    'expecttest==0.1.6',
```

This is pretty annoying, I don't want have to update six locations every time I upgrade the version on my dependency.

The worst offender is requirements-ci.txt vs pip-requirements-macOS.txt. These requirements files are substantially the same. Using this script (ChatGPT authored):

```
import subprocess
import requirements

def get_dependency_graph(file_path):
    reqs = requirements.parse(open(file_path, 'r').read())
    return {req.name: req for req in reqs}

def compare_dependency_graphs(graph1, graph2):
    for name, req1 in graph1.items():
        req2 = graph2.get(name)
        if req2 is None:
            print(f"{name} is missing in graph2")
        elif req1 != req2:
            print(f"{name} has different versions: {req1} vs {req2}")
    
    for name, req2 in graph2.items():
        req1 = graph1.get(name)
        if req1 is None:
            print(f"{name} is missing in graph1")

# Parse the first requirements.txt file
graph1 = get_dependency_graph(".ci/docker/requirements-ci.txt")

# Parse the second requirements.txt file
graph2 = get_dependency_graph(".github/requirements/pip-requirements-macOS.txt")

# Compare the two dependency graphs
compare_dependency_graphs(graph1, graph2)
```

we find

```
click is missing in graph2
coremltools is missing in graph2
dill is missing in graph2
flatbuffers is missing in graph2
hypothesis has different versions: <Requirement: "hypothesis==5.35.1"> vs <Requirement: "hypothesis==6.56.4">
junitparser is missing in graph2
lark is missing in graph2
mypy is missing in graph2
networkx has different versions: <Requirement: "networkx==2.8.8"> vs <Requirement: "networkx==2.8.7">
numba has different versions: <Requirement: "numba==0.55.2 ; python_version == "3.10""> vs <Requirement: "numba<=0.49.1; platform_machine != "arm64"">
opt-einsum has different versions: <Requirement: "opt-einsum==3.3"> vs <Requirement: "opt-einsum>=3.3">
pillow is missing in graph2
protobuf is missing in graph2
psutil has different versions: <Requirement: "psutil"> vs <Requirement: "psutil==5.9.1">
pytest-rerunfailures has different versions: <Requirement: "pytest-rerunfailures>=10.3"> vs <Requirement: "pytest-rerunfailures==10.3">
scikit-image is missing in graph2
tb-nightly is missing in graph2
lintrunner is missing in graph2
ghstack is missing in graph2
jinja2 is missing in graph2
pywavelets is missing in graph2
lxml is missing in graph2
mpmath is missing in graph1
nvidia-ml-py is missing in graph1
packaging is missing in graph1
sympy is missing in graph1
filelock is missing in graph1
```

The conda environment thing is also pretty weird.

### Versions

main

cc @seemethere @malfet @pytorch/pytorch-dev-infra @ZainRizvi @kit1980 @huydhn @clee2000