You can make a simple geometry nodes setup that instantiates an object along a curve without deforming the individual object instances.
Here's the result:
And here is the node setup:
Here's a breakdown of the nodes setup:
The idea is that you'll instantiate an object at regular intervals along the length of a curve, and they'll be rotated along the tangent of the curve, so their rotation follow the flow of the curve.
If we just instantiate objects on the points of the curve it won't work, because the points of the curve will most likely not be spread evenly along the curve. So first we need to resample the curve, making the points spread evenly along the curve.
So we use the Resample Curve node set to Count. We feed the Geometry input into the Curve input of the node. To get our "count", we get the curve length and multiply it by and integer parameter that I called "NumberOfObjectsPerLength", meaning the number of objects that will be instantiated per unit (per meter in this case) of length of the curve.
So this will give us a curve with the points evenly spread along it, and a parameter that we can easily edit in the modifiers panel to increase or decrease the number of grains on our wheat stem.
Next we use "Instance on Points" to instantiate our object (in this case a "GrainLump", which is a single object composed of three grains joined together. On the Rotation input of this node we plug an "Align Euler to Vector" node that gets the curve tangent vector and spits out an Euler Rotation aligned to that vector, so each grain lump will be instantiated with its rotation aligned to the curve flow.
So that could be everything, but I thought it would be nice to add a little bit of randomness so it doesn't look so tidy, so I added a "Rotate Instances" node and plugged a Random Value node (set to Vector) in the Rotation input, and used a Combine XYZ node to create the Max possible value of the Random Value node. I created another input parameter called "MaxRandomRotation" and plugged in the Z of the Combine XYZ, leaving the other axis set to zero. So the random value will always have X and Y be zero, but Z will be something between zero and whatever you set as the MaxRandomRotation parameter.
That way you can add a little bit of randomness to the rotation of the grains by increasing this value.
You could also do basically the same thing to add some randomness to the scale of the grains.